Javascript 所选的Angular指令不会将控制器的$watch作为

Javascript 所选的Angular指令不会将控制器的$watch作为,javascript,angularjs,Javascript,Angularjs,我跟随了卢卡斯·鲁巴尔克@simpulton的作品,也发现并阅读了关于他的作品的文章 我已经跟踪了这两个选项,并显示了所选的选择框。我遇到的问题是,我需要调用“selected:updated”来刷新selected,以便来自控制器的数据将填充selectoptions数据来自$promise/web服务 我使用一个控制器来获取数据并创建5个不同的选择框。5个不同的过滤器列表。我使用控制器作为语法和ui路由器 从我所能说的来看,考虑到我所遵循的示例,它应该是有效的,但是 element.trig

我跟随了卢卡斯·鲁巴尔克@simpulton的作品,也发现并阅读了关于他的作品的文章

我已经跟踪了这两个选项,并显示了所选的选择框。我遇到的问题是,我需要调用“selected:updated”来刷新selected,以便来自控制器的数据将填充selectoptions数据来自$promise/web服务

我使用一个控制器来获取数据并创建5个不同的选择框。5个不同的过滤器列表。我使用控制器作为语法和ui路由器

从我所能说的来看,考虑到我所遵循的示例,它应该是有效的,但是

element.trigger('chosen:updated');
永远不会调用,并且所选的选项当然不会显示选项。检查DOM时,选项就在那里,它们是从控制器数据创建的。我就是打不到“更新”的电话来开火

这是指令:

angular.module('reporting.directive')

.directive("chosen", function () {

    var linker = function (scope, element, attr) {
        var list = attr['chosen'];

        scope.$watch(list, function () {
            element.trigger('chosen:updated');
        });


        element.chosen({
            single_backstroke_delete: false,
            search_contains: true,
            no_results_text: "Oops, nothing found!",
            width: "100%"
        });
    };

    return {
        restrict: 'A',
        link: linker
    }
})
;
angular.module('reporting.directive')

.directive("chosen", function () {

    var linker = function (scope, element, attr) {

        scope.$watch(
            function (scope) {
                return scope.selectsController.optionData
            }, function () {
                element.trigger('chosen:updated');
                console.log("fired for " + attr["id"]);
            });



        element.chosen({
            single_backstroke_delete: false,
            search_contains: true,
            no_results_text: "Oops, nothing found!",
            width: "100%"
        });
    };

    return {
        restrict: 'A',
        link: linker
    }
})
;
以及HTML/模板:

<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Cost Center</div>
    <select id="costcenter" class="chosen-select" chosen="selectsController.datacostcenter" data-placeholder="ALL" multiple
            ng-model="csSelect1" ng-options="cc2 as cc2 for cc2 in selectsController.datacostcenter"></select>
</div>
<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Provider Name</div>
    <select id="providername" class="chosen-select" chosen="selectsController.dataprovname" data-placeholder="ALL" multiple ng-change="$state.forceReload()"
            ng-model="csSelect2" ng-options="provname as provname for provname in selectsController.dataprovname"></select>
</div>

<SNIP> 

<div class="col-xs-12 col-md-2">
    <input id="hubmenuitemdescription" value="" />
</div>
编辑2 我已经确认$watch正在触发该元素;在$promise解决之前。我在范围上有数据变量,并且以我理解的方式引用它。更新代码如下

我仍然不明白为什么要使用这个范围。$watch'selectsController.optionData'。。。当optionData像我认为应该的那样更新时,不会被调用

更新控制器:

angular.module('reporting.controller')

.controller('SelectsController', function (SelectDataRetrival,$q) {
    var selectsController = this;

    selectsController.optionData = [];

    var datacostcenter   = SelectDataRetrival.query({ stuff: stuff });
    var dataprovname     = SelectDataRetrival.query({ stuff: stuff2 });

    $q.all([datacostcenter.$promise, dataprovname.$promise])
            .then(function (results) {
                for (var i = 0; i < results.length; i++) {
                    selectsController.optionData.push(results[i]);
                }
                console.log("controller finished, data assigned"); 
            });
})
;
angular.module('reporting.controller')

.controller('SelectsController', function (SelectDataRetrival,$q) {
    var selectsController = this;

    SelectDataRetrival.query({ stuff: stuff })
        .$promise.then(function (results) {
            selectsController.datacostcenter = results;
        });
    SelectDataRetrival.query({ stuff: stuff2 })
        .$promise.then(function (results) {
            selectsController.dataprovname = results;
        });

})
;
您的var列表未绑定到$scope,因此无法监视。首先将其绑定到$scope

var linker = function (scope, element, attr) {
    scope.list = attr['chosen'];

    scope.$watch("list", function () {
        element.trigger('chosen:updated');
    });
}

我正在分享angularJS的一些有用的概念,请参考下面的要点

承诺在控制器调用的生命周期内仅执行一次。 当我们对任何变量应用watch时,watch将触发该变量的所有赋值。 var list=attr['selected']

作用域。$watchlist,函数{ 元素。触发器“已选择:已更新”; };

list=attr[“再次选择”]


在这个场景中,列表被分配了2次,所以watch将触发两次。

我找到了如何让它工作的方法。我不是百分之百地了解原因,但我确信以下更改会导致所选的select更新,并且由于数据/范围的更改而触发$watch,从而按预期进行更新

我将数据发送到隔离作用域中的指令中,然后观察该变量。在通过控制器As将其分配给作用域之前,我还必须等待承诺得到解决。如果我不等待承诺,我就不会得到更新

指令:

angular.module('reporting.directive')

.directive("chosen", function () {

    var linker = function (scope, element, attr) {

        scope.$watch("data", function () {
                element.trigger('chosen:updated');
                console.log("fired for " + attr["id"]);
            });

        element.chosen({
            single_backstroke_delete: false,
            search_contains: true,
            no_results_text: "Oops, nothing found!",
            width: "100%"
        });
    };

    return {
        restrict: 'A',
        link: linker,
        scope: {
            data: "="
        }
    }
})
;
HTML/模板:

<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Cost Center</div>
    <select id="costcenter" class="chosen-select" chosen data-placeholder="ALL" multiple
            ng-model="csSelect1" ng-options="cc2 as cc2 for cc2 in selectsController.datacostcenter" data="selectsController.datacostcenter"></select>
</div>
<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Provider Name</div>
    <select id="providername" class="chosen-select" chosen data-placeholder="ALL" multiple ng-change="$state.forceReload()"
            ng-model="csSelect2" ng-options="provname as provname for provname in selectsController.dataprovname" data="selectsController.dataprovname"></select>
</div>

attr['selected']的计算结果是一个永远不会更改的字符串。列表作为一个基本值变量将永远不会更改我添加了控制器代码以供参考。我看到了错误,并且看到了Lukas的版本如何满足范围中的需要。我对代码进行了更改,但仍然没有刷新所选框。我添加了一个console.log来查看$watch是否被调用,事实确实如此。那么为什么我的选择中没有选项呢?如果我手动调用$'costcenter'。触发'Selected:updated',选项将显示。我会继续处理这个问题,任何额外的指针都是受欢迎的。看起来$watch在$promise返回之前第一次被调用,所以数组是空的,没有选项。既然$promise已经解决,为什么$watch没有第二次被调用?我错过了什么?@ThaigoPXP谢谢你的帮助,你让我对scope有了更深的思考。
<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Cost Center</div>
    <select id="costcenter" class="chosen-select" chosen data-placeholder="ALL" multiple
            ng-model="csSelect1" ng-options="cc2 as cc2 for cc2 in selectsController.datacostcenter" data="selectsController.datacostcenter"></select>
</div>
<div class="col-xs-12 col-md-2">
    <div class="filterboxtext">Provider Name</div>
    <select id="providername" class="chosen-select" chosen data-placeholder="ALL" multiple ng-change="$state.forceReload()"
            ng-model="csSelect2" ng-options="provname as provname for provname in selectsController.dataprovname" data="selectsController.dataprovname"></select>
</div>
angular.module('reporting.controller')

.controller('SelectsController', function (SelectDataRetrival,$q) {
    var selectsController = this;

    SelectDataRetrival.query({ stuff: stuff })
        .$promise.then(function (results) {
            selectsController.datacostcenter = results;
        });
    SelectDataRetrival.query({ stuff: stuff2 })
        .$promise.then(function (results) {
            selectsController.dataprovname = results;
        });

})
;