Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 指令未使用ControllerA和bindToController使用异步数据更新视图_Angularjs_Asynchronous_Controller_Directive - Fatal编程技术网

Angularjs 指令未使用ControllerA和bindToController使用异步数据更新视图

Angularjs 指令未使用ControllerA和bindToController使用异步数据更新视图,angularjs,asynchronous,controller,directive,Angularjs,Asynchronous,Controller,Directive,我在获取更新视图的指令时遇到了一些问题 在我的控制器中,我为指令的属性设置初始值。然后,2秒钟后,我将更新vm.listObjectSelected,以测试其异步行为 但是,该视图没有反映更新 控制器: var listObject = [{"display":"display1", "value":"value1"}, {"display":"display2", "value":"value2"}, {"display":"display3", "value":"value3"}]

我在获取更新视图的指令时遇到了一些问题

在我的控制器中,我为
指令的属性设置初始值。然后,2秒钟后,我将更新
vm.listObjectSelected
,以测试其异步行为

但是,该视图没有反映更新

控制器

    var listObject = [{"display":"display1", "value":"value1"}, {"display":"display2", "value":"value2"}, {"display":"display3", "value":"value3"}]

    vm.listObject = listObject
    vm.listObjectSelected = [{"display":"display1", "value":"value1"}]

    $timeout(function(){

        vm.listObjectSelected = [{"display":"display1", "value":"value1"}, {"display":"display3", "value":"value3"}]

    }, 2000)
HTML

<tiki-list max="" type="multi" list="editController.listObject" selected="editController.listObjectSelected"></tiki-list>

指令

(function(){

    'use strict';

    angular.module("tiki").directive("tikiList", tikiList)

    function tikiList(helper){

        var directive = {

            restrict:"EA",
            scope:{

                list: "=", //the object to repeat over, this contains 2 array's
                retunObject: "=", //the array that is outputted
                selected: "=", //preselected values
                max: "=", //maximum range, other elements are greyed out, starts at 0
                title:"@title", //the title of this list
                type:"@type", //[single, multi]

            },
            templateUrl:"js/directive/list.html",
            link:link,
            bindToController: true,
            controllerAs:"vm",
            controller:controller

        }

        return directive

        function link(scope, el, attr, ctrl){

            scope.vm.onClick = onClick

            // preprocess the "list" if there is a "selected" attribute
            // the "selected" attribute is an object that contains the selected items
            // return a "selectedItems" array containing the indeces of matching display names
            // add the .active property to the "list" object to the correct indeces

            if(scope.vm.selected){

                var selectedItems = helper.isItemInList(helper.createArrayFromProperty(scope.vm.selected, "display"), helper.createArrayFromProperty(scope.vm.list, "display"))

                for(var i = 0; i < selectedItems.length; i++){

                    scope.vm.list[selectedItems[i]].active = true

                }

            }

            // add the property .disabled to the "list" if there is a max attribute
            // the property will be added to all indeces that exceed the max value

            if(scope.vm.max){

                for(var y = 0; y < scope.vm.list.length; y++){

                    if(y >= scope.vm.max){

                        scope.vm.list[y].disabled = true

                    }

                }

            }

            function onClick(index){

                // only allow items that are in range of the "max" attribute are allowed to be clicked

                if(!scope.vm.max || index < scope.vm.max){

                    if(scope.vm.type === "single"){

                        angular.forEach(scope.vm.list, function(val, key){

                            scope.vm.list[key].active = false

                        })

                        scope.vm.list[index].active = true

                    }

                    if(scope.vm.type === "multi"){

                        scope.vm.list[index].active = !scope.vm.list[index].active

                    }

                }

            }

            scope.vm.listing = scope.vm.list

        }


    }

    controller.$inject = [];

    function controller(){




    }


})()
  <ul class="listOptions">
    <li class="listOptions-title" ng-class="{'show':title}">{{vm.title}}</li>
    <li ng-click="vm.onClick($index)" ng-class="{'active':list.active, 'disabled':list.disabled}" ng-repeat="list in vm.listing track by $index">{{list.display}}</li>
  </ul>
(函数(){
"严格使用",;
角度模块(“tiki”)指令(“tikiList”,tikiList)
函数提示列表(帮助器){
var指令={
限制:“EA”,
范围:{
列表:“=”,//要重复的对象,它包含2个数组
retunObject:“=”,//输出的数组
选定:“=”,//预选值
max:“=”,//最大范围,其他元素灰显,从0开始
标题:“@title”,//此列表的标题
类型:“@type”、/[单个、多个]
},
templateUrl:“js/directive/list.html”,
链接:链接,
bindToController:对,
controllerAs:“虚拟机”,
控制器:控制器
}
返回指令
功能链接(范围、el、属性、ctrl){
scope.vm.onClick=onClick
//如果存在“选定”属性,则预处理“列表”
//“选定”属性是包含选定项的对象
//返回一个“selectedItems”数组,其中包含匹配显示名称的索引
//将.active属性添加到“list”对象的正确索引中
if(scope.vm.selected){
var selectedItems=helper.isItemInList(helper.createArrayFromProperty(scope.vm.selected,“显示”),helper.createArrayFromProperty(scope.vm.list,“显示”))
对于(变量i=0;i=scope.vm.max){
scope.vm.list[y].disabled=true
}
}
}
函数onClick(索引){
//只允许单击“最大”属性范围内的“允许”项
如果(!scope.vm.max | | index
指令模板

(function(){

    'use strict';

    angular.module("tiki").directive("tikiList", tikiList)

    function tikiList(helper){

        var directive = {

            restrict:"EA",
            scope:{

                list: "=", //the object to repeat over, this contains 2 array's
                retunObject: "=", //the array that is outputted
                selected: "=", //preselected values
                max: "=", //maximum range, other elements are greyed out, starts at 0
                title:"@title", //the title of this list
                type:"@type", //[single, multi]

            },
            templateUrl:"js/directive/list.html",
            link:link,
            bindToController: true,
            controllerAs:"vm",
            controller:controller

        }

        return directive

        function link(scope, el, attr, ctrl){

            scope.vm.onClick = onClick

            // preprocess the "list" if there is a "selected" attribute
            // the "selected" attribute is an object that contains the selected items
            // return a "selectedItems" array containing the indeces of matching display names
            // add the .active property to the "list" object to the correct indeces

            if(scope.vm.selected){

                var selectedItems = helper.isItemInList(helper.createArrayFromProperty(scope.vm.selected, "display"), helper.createArrayFromProperty(scope.vm.list, "display"))

                for(var i = 0; i < selectedItems.length; i++){

                    scope.vm.list[selectedItems[i]].active = true

                }

            }

            // add the property .disabled to the "list" if there is a max attribute
            // the property will be added to all indeces that exceed the max value

            if(scope.vm.max){

                for(var y = 0; y < scope.vm.list.length; y++){

                    if(y >= scope.vm.max){

                        scope.vm.list[y].disabled = true

                    }

                }

            }

            function onClick(index){

                // only allow items that are in range of the "max" attribute are allowed to be clicked

                if(!scope.vm.max || index < scope.vm.max){

                    if(scope.vm.type === "single"){

                        angular.forEach(scope.vm.list, function(val, key){

                            scope.vm.list[key].active = false

                        })

                        scope.vm.list[index].active = true

                    }

                    if(scope.vm.type === "multi"){

                        scope.vm.list[index].active = !scope.vm.list[index].active

                    }

                }

            }

            scope.vm.listing = scope.vm.list

        }


    }

    controller.$inject = [];

    function controller(){




    }


})()
  <ul class="listOptions">
    <li class="listOptions-title" ng-class="{'show':title}">{{vm.title}}</li>
    <li ng-click="vm.onClick($index)" ng-class="{'active':list.active, 'disabled':list.disabled}" ng-repeat="list in vm.listing track by $index">{{list.display}}</li>
  </ul>
  • {{{vm.title}
  • {{{list.display}
我想这和controllerAs有点关系,但我不知道该怎么办


thx,

我认为原因是数组是引用类型。当您在服务或异步步骤中更改数据时,数据点会转到内存中的新位置,但指令或控制器中的数据不会更改

不要像这样编写函数:

$timeout(function(){

    vm.listObjectSelected = [{"display":"display1", "value":"value1"}, {"display":"display3", "value":"value3"}]

}, 2000)
您应该尝试这样做:

$(timeout(function(){vm.listObjectSelected.push({you need data here})},200)
或者你可以使用一个承诺,你可以返回一个承诺并在指令中得到它,使用

promise.then(function(){//let data = service.data again}

希望这能对您有所帮助。

为什么您总是使用
scope.vm
?如果您将
controllerAs
bindToController
一起使用,则可以直接访问
对象上的隔离作用域属性,例如
此.选定的
。使用指令定义的
bindToController
属性,隔离作用域的所有属性将自动绑定到控制器,而不是作用域。没有必要使用
scope.vm
。我之所以使用scope.vm,是因为我试图遵循以下样式指南:在
$timeout
内执行的操作超出了角度摘要周期。您需要在
vm.listObjectSelected=…
之后调用
$scope.$digest()
内部
$timout
,因为在指令
scope.vm.listing
scope.vm.list
中,当您将控制器
listObject
设置为新数组时,将不会指向相同的引用。因此,尽管更新了
scope.vm.list
,但您的
scope.vm.listing
不会更新。只需将
ng repeat
设置为使用
scope.vm.list
而不是
scope.vm.listing
,就可以了。我误解了您在控制器中选择的
listObject
listObject
。您应该使用
$watch
来注意
listObjectSelected
中的更改。