AngularJS:当一个模型元素被从模型阵列剪接不更新纳克重复列表 [英] AngularJS : ng-repeat list is not updated when a model element is spliced from the model array

查看:187
本文介绍了AngularJS:当一个模型元素被从模型阵列剪接不更新纳克重复列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之间有两个控制器和共享数据与app.factory功能。
第一个控制器增加了模型阵列(pluginsDisplayed)点击一个链接时,在一个小部件。所述插件推入到阵列和这种变化反映到视图(使用纳克重复到显示阵列的内容):

 < D​​IV NG重复=pluginD在pluginsDisplayed>
    < D​​IV k2plugin pluginname ={{pluginD.name}}pluginid ={{pluginD.id}}>< / DIV>
< / DIV>

小部件是建立在三个指令,k2plugin,删除和调整大小建造。删除指令增加了一个跨度为k2plugin指令的模板。当点击所述展,到共享阵列右元素与删除方法Array.splice()。共享阵列正确更新,但变化的不可以反映在视图中。然而,当加入另一个元件时,该删除后,该视图正确地刷新和元件未示出previously缺失

什么我收到错了吗?你能解释我为什么不起作用?
有没有更好的方式做什么,我想用角呢?

这是我的index.html:

 <!DOCTYPE HTML>
< HTML和GT;
  < HEAD>
    &所述; SCRIPT SRC =htt​​ps://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js>
    < / SCRIPT>
    &所述; SCRIPT SRC =main.js>&下; /脚本>
  < /头>
  <身体GT;
    < D​​IV NG-应用=livePlugins>
        < D​​IV NG控制器=pluginlistctrl>
            <跨度>添加一个{{pluginList.length}}插件< / SPAN>
            <李NG重复=插件中pluginList>
                &所述;跨度>&下; A HREF =纳克点击=加()> {{plugin.name}}&下; / A>&下; /跨度>
            < /李>
        < / DIV>
        < D​​IV NG控制器=k2ctrl>
            < D​​IV NG重复=pluginD在pluginsDisplayed>
                < D​​IV k2plugin pluginname ={{pluginD.name}}pluginid ={{pluginD.id}}>< / DIV>
            < / DIV>
        < / DIV>
    < / DIV>
  < /身体GT;
< / HTML>

这是我的main.js:

  VAR应用= angular.module(livePlugins,[]);app.factory(数据,函数(){
    返回{pluginsDisplayed:[]};
});app.controller(pluginlistctrl功能($范围,数据){
    $ scope.pluginList = {[名字:plugin1},{名字:plugin2},{名字:plugin3}];
    $ scope.add =功能(){
        的console.log(叫上添加,this.plugin.name,this.pluginList);
        变种newPlugin = {};
        newPlugin.id = this.plugin.name +'_'+(新的Date())的getTime()。
        newPlugin.name = this.plugin.name;
        Data.pluginsDisplayed.push(newPlugin);
    }
})app.controller(k2ctrl功能($范围,数据){
    $ scope.pluginsDisplayed = Data.pluginsDisplayed;    $ scope.remove =功能(元素){
        的console.log(叫去除,this.pluginid,元素);        VAR LEN = $ scope.pluginsDisplayed.length;
        变种指数= -1;        //找到数组中的元素
        对于(VAR I = 0; I< LEN; I + = 1){
            如果($ scope.pluginsDisplayed [I] .ID === this.pluginid){
                指数= I;
                打破;
            }
        }        //删除元素
        如果(指数!== -1){
            的console.log(从数组移除元件,索引:,索引);
            $ scope.pluginsDisplayed.splice(指数,1);
        }    }
    $ scope.resize =功能(){
        的console.log(被叫调整大小,this.pluginid);
    }
})app.directive(k2plugin功能(){
    返回{
        限制:A,
        适用范围:真,
        链接:功能(范围,元素,ATTRS){
            的console.log(创建插件);            //这是不行的immediatley。属性pluginname将是不确定的
            //只要此被调用。
            scope.pluginname =载入中...
            scope.pluginid = attrs.pluginid;            //观察更改属性插值
            ATTRS。观察$('pluginname',功能(价值){
                的console.log('pluginname改变值+值);
                scope.pluginname = attrs.pluginname;
            });            //观察更改属性插值
            ATTRS。观察$('pluginid',功能(价值){
                的console.log('pluginid改变值+值);
                scope.pluginid = attrs.pluginid;
            });
        },
        模板:< D​​IV> {{pluginname}}<跨度调整> _< / SPAN><跨度删除> X< / SPAN>中+
                       < D​​IV>插件DIV< / DIV>中+
                  < / DIV>中,
        替换:真
    };
});app.directive(删除功能(){
    返回功能(范围,元素,ATTRS){
        element.bind(的mousedown功能(){
            scope.remove(元件);
        })
    };});app.directive(调整大小功能(){
    返回功能(范围,元素,ATTRS){
        element.bind(的mousedown功能(){
            scope.resize(元件);
        })
    };});


解决方案

每当你做某种形式的angularjs,比如做一个Ajax调用使用jQuery,或事件绑定到一个元素之外的操作就像你在这里你需要让角知道进行自我更新。下面是你需要做的code变化:

  app.directive(删除功能(){
    返回功能(范围,元素,ATTRS){
        element.bind(的mousedown功能(){
            scope.remove(元件);
            。范围$适用();
        })
    };});app.directive(调整大小功能(){
    返回功能(范围,元素,ATTRS){
        element.bind(的mousedown功能(){
            scope.resize(元件);
            。范围$适用();
        })
    };});

下面是它的文档:<一href=\"http://docs.angularjs.org/api/ng.$rootScope.Scope#$apply\">https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply

I have two controllers and share data between them with an app.factory function. The first controller adds a widget in the model array (pluginsDisplayed) when a link is clicked. The widget is pushed into the array and this change is reflected into the view (that uses ng-repeat to show the array content):

<div ng-repeat="pluginD in pluginsDisplayed">
    <div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>

The widget is built upon three directives, k2plugin, remove and resize. Remove directive adds a span to the template of the k2plugin directive. When said span is clicked, the right element into the shared array is deleted with Array.splice(). The shared array is correctly updated, but the change is not reflected in the view. However, when another element is added, after the remove, the view is refreshed correctly and the previously-deleted element is not shown.

What I'm getting wrong? Could you explain me why this doesn't work? Is there a better way to do what I'm trying to do with Angular?

This is my index.html:

<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js">
    </script>
    <script src="main.js"></script>
  </head>
  <body>
    <div ng-app="livePlugins">
        <div ng-controller="pluginlistctrl">
            <span>Add one of {{pluginList.length}} plugins</span>
            <li ng-repeat="plugin in pluginList">
                <span><a href="" ng-click="add()">{{plugin.name}}</a></span>
            </li>
        </div>
        <div ng-controller="k2ctrl">
            <div ng-repeat="pluginD in pluginsDisplayed">
                <div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
            </div>
        </div>
    </div>
  </body>
</html>

This is my main.js:

var app = angular.module ("livePlugins",[]);

app.factory('Data', function () {
    return {pluginsDisplayed: []};
});

app.controller ("pluginlistctrl", function ($scope, Data) {
    $scope.pluginList = [{name: "plugin1"}, {name:"plugin2"}, {name:"plugin3"}];
    $scope.add = function () {
        console.log ("Called add on", this.plugin.name, this.pluginList);
        var newPlugin = {};
        newPlugin.id = this.plugin.name + '_'  + (new Date()).getTime();
        newPlugin.name = this.plugin.name;
        Data.pluginsDisplayed.push (newPlugin);
    }
})

app.controller ("k2ctrl", function ($scope, Data) {
    $scope.pluginsDisplayed = Data.pluginsDisplayed;

    $scope.remove = function (element) {
        console.log ("Called remove on ", this.pluginid, element);

        var len = $scope.pluginsDisplayed.length;
        var index = -1;

        // find the element in the array
        for (var i = 0; i < len; i += 1) {
            if ($scope.pluginsDisplayed[i].id === this.pluginid) {
                index = i;
                break;
            }
        }

        // remove the element
        if (index !== -1) {
            console.log ("removing the element from the array, index: ", index);
            $scope.pluginsDisplayed.splice(index,1);
        }

    }
    $scope.resize = function () {
        console.log ("Called resize on ", this.pluginid);
    }
})

app.directive("k2plugin", function () {
    return {
        restrict: "A",
        scope: true,
        link: function (scope, elements, attrs) {
            console.log ("creating plugin");

            // this won't work immediatley. attribute pluginname will be undefined
            // as soon as this is called.
            scope.pluginname = "Loading...";
            scope.pluginid = attrs.pluginid;

            // observe changes to interpolated attribute
            attrs.$observe('pluginname', function(value) {
                console.log('pluginname has changed value to ' + value);
                scope.pluginname = attrs.pluginname;
            });

            // observe changes to interpolated attribute
            attrs.$observe('pluginid', function(value) {
                console.log('pluginid has changed value to ' + value);
                scope.pluginid = attrs.pluginid;
            });
        },
        template: "<div>{{pluginname}} <span resize>_</span> <span remove>X</span>" +
                       "<div>Plugin DIV</div>" + 
                  "</div>",
        replace: true
    };
});

app.directive("remove", function () {
    return function (scope, element, attrs) {
        element.bind ("mousedown", function () {
            scope.remove(element);
        })
    };

});

app.directive("resize", function () {
    return function (scope, element, attrs) {
        element.bind ("mousedown", function () {
            scope.resize(element);
        })
    };

});

解决方案

Whenever you do some form of operation outside of angularjs, such as doing an ajax call with jquery, or binding an event to an element like you have here you need to let angular know to update itself. Here is the code change you need to do:

app.directive("remove", function () {
    return function (scope, element, attrs) {
        element.bind ("mousedown", function () {
            scope.remove(element);
            scope.$apply();
        })
    };

});

app.directive("resize", function () {
    return function (scope, element, attrs) {
        element.bind ("mousedown", function () {
            scope.resize(element);
            scope.$apply();
        })
    };

});

Here are the docs on it: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply

这篇关于AngularJS:当一个模型元素被从模型阵列剪接不更新纳克重复列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆