angularjs - Angular -ui-select2和breezejs : load ajax list after typing in 2 characters

标签 angularjs breeze angularjs-select2

我有一个项目,我正在使用 BreezeJS 从我的网络服务器获取数据。我将 AngularJS 与 ui-select2 模块一起使用。目前,当我加载页面时,breezejs 会调用以获取我转储到作用域变量中的数据。从那里,select2 可以轻松地引用它并进行相应的构建。

如果我想要 ajaxify 东西,它会变得非常棘手。我希望能够使用 select2 的 ajax 或查询支持,但我不想使用它来获取数据,而是想使用 Breezejs 来做到这一点。因此,在页面加载期间,直到我在进行 ajax 获取之前开始输入 X 个最少字符之前,不会加载任何内容。

限制: 我不想使用 select2 的“ajax”获取数据。我希望 BreezeJS 处理服务调用。当我使用 ajax 时,每次我按下一个字符时,它都会进行 ajax 调用以过滤结果(类似于自动完成)。我只希望列表加载一次,然后使用 native 过滤。

这是我到目前为止所拥有的:

breezejs - StateContext.JS

m.app.factory('StateContext', ['$http', function ($http) {
    configureBreeze();

    var dataService = new breeze.DataService({
        serviceName: "/Map/api",
        hasServerMetadata: false
    });

    var manager = new breeze.EntityManager({ dataService: dataService});

    var datacontext = {
        getAllStates: getAllStates
    };
    return datacontext;


    function getAllStates() {
        var query = breeze.EntityQuery
                .from("States");
        return manager.executeQuery(query);
    }


    function configureBreeze() {
        breeze.config.initializeAdapterInstances({ dataService: "webApi" });
    }
}]);

这可以正常工作并正确返回我的 json 对象。

这是我调用该服务的方式:

m.app.controller('LocationCtrl', ['$scope', 'StateContext', function ($scope, StateContext) {

    $scope.getAllStates = function () {
        StateContext.getAllStates().then(stateQuerySucceeded).fail(queryFailed);
    }
    $scope.getAllStates();


    $scope.states = [];
    function stateQuerySucceeded(data) {
        data.results.forEach(function (item) {
            $scope.states.push(item);
        });
        $scope.$apply();

        console.log("Fetched States");
    }

    function queryFailed(error) {
        console.log("Query failed");
    }

    $scope.select2StateOptions = {
        placeholder: "Choose a State",
        allowClear: true,
        minimumInputLength: 2
    };
}

这是我的 html:

<div ng-app="m" id="ng-app">
    ...
    ...

    <select ui-select2="select2StateOptions" ng-model="LocationModel.State">
        <option value=""></option>
        <option ng-repeat="state in states" value="{{state.id}}">{{state.name}}</option>
    </select>
</div>

当前,html select2 控件在页面加载时加载。但我希望拥有它,这样当我输入超过 2 个字符时,我就能够调用 $scope.getAllStates();作为 ajax 调用。在为 webapi 配置 BreezeAdapter 时,BreezeJS 已经原生使用了 ajax。

我正在考虑使用select2的ajax或查询调用..但我宁愿使用 Breeze 来获取数据,因为它使查询可扩展,并且我不想违反我的设计模式,或使代码更难维护,而且我不希望每次在文本框中输入新字符时都进行 ajax 调用,我只希望它发生一次。

关闭尝试:

将我的 html 更改为:

<!-- Select2 needs to make this type="hidden" to use query or ajax, then it applies the UI skin afterwards -->
<input type="hidden" ui-select2="select2StateOptions" ng-model="LocationModel.State" /><br />

在我的 Controller 中,更改 select2StateOptions:

$scope.select2StateOptions = {
    placeholder: "Choose a State",
    allowClear: true,
    minimumInputLength: 2,
    query: function (query) {
        debugger;
        var data = StateContext.getAllStates().then(stateQuerySucceeded).fail(queryFailed);
    }
};

问题就在这里。 BreezeJS 使用 Q 库,它利用了一种称为“promise”的东西;这是一个 promise ,在进行 ajax 调用后将返回数据。这样做的问题是,查询函数期望填充数据,但调用“stateQuerySucceeded”函数的 promise 是从查询函数返回后做出的。

所以它首先命中查询函数。然后点击 getAllStates()。从查询返回(未填充任何内容),然后调用“stateQuerySucceeded”。

换句话说,即使我已经能够获取数据,但这已经太晚了.. select2 的查询函数没有在正确的时间接收到数据,并且我的 html select 卡在“正在搜索...”上搜索 spinner.gif。

最佳答案

我真的不知道这个angular-ui-select2 control 。我认为文档的相关部分是这个例子:

$("#e5").select2({
    minimumInputLength: 2,
    query: function (query) {
       var data = {results: []}, i, j, s;
        // simulate getting data from the server
        for (i = 1; i < 5; i++) {
            s = "";
            for (j = 0; j < i; j++) {s = s + query.term;}
            data.results.push({id: query.term + i, text: s});
        }
        query.callback(data);
    }
});

我将忽略这样一个事实:您似乎对使用用户在查询中输入的两个或多个字符不感兴趣(也许您只是将其遗漏了)。我将继续进行在我看来无意义的操作,即在用户输入任意两个字母后获取所有状态。

我认为您缺少的是 query.callback 的作用,它是在数据到达时告诉“angular-ui-select2”。我猜您想在成功函数中调用query.callback

$scope.select2StateOptions = {
    placeholder: "Choose a State",
    allowClear: true,
    minimumInputLength: 2,
    query: function (query) {
        StateContext.getAllStates()
                    .then(querySucceeded).catch(queryFailed);

       function querySucceeded(response) {
            // give the {results:data-array} to the query callback
            query.callback(response);
       }

       function queryFailed(error) {
           // I don't know what you're supposed to do.
           // maybe return nothing in the query callback?
           // Tell the user SOMETHING and then
           query.callback({results:[]});      
       }
    }
};

正如我所说,我只是根据快速阅读文档进行猜测。将此答案视为一个“提示”,请不要指望我会遵循并使其真正发挥作用。

关于angularjs - Angular -ui-select2和breezejs : load ajax list after typing in 2 characters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21586773/

相关文章:

java - Spring Rest Controller POST 请求不起作用

javascript - 使用 BreezeJS 在 Durandal 中显示模态

javascript - 如何使用angularjs在选择标签中使用select2显示标签

angularjs - allowClear ="true"在 angular-ui 选择中不起作用

javascript - 为视频而不是图像实现 Angular Masonry

javascript - Angular JS - 如何在 ng-repeat 中添加额外的 DIV

javascript - Breeze中使用 'take'方法查询时可能出现的bug

javascript - Angularjs ui-select (select2) 不使用 'Controller as' 语法没有被选中

javascript - 预检响应具有无效的 HTTP 状态代码 : 401 angular

javascript - 在没有 Entity Framework 的情况下使用 Breeze.js