AnguarJS 1.3使用一次性绑定手动更新绑定

AngualrJS 1.3 manually update binding with one time binding

本文关键字:绑定 更新 一次性 AnguarJS      更新时间:2024-03-18

我想在视图{{::vm.list}}中使用一次性绑定。这一切都很好。但是,单击一个按钮,我想刷新vm.list。

我似乎不知道如何手动触发vm.list进行更新。也许一次性约束不是答案?

下面是一个jsfiddle样板示例:http://jsfiddle.net/KamelJabber/e4nexvay/2/

(function () {
    var c1 = function Controller1() {
        var vm = this;
        var addCount = 1;
        vm.list = [{
            Id: 1,
            Text: "Blue One"
        }, {
            Id: 2,
            Text: "Blue Two"
        }, {
            Id: 3,
            Text: "Blue Three"
        }];
        vm.AddnRefresh = function () {
            vm.list.push({
                Id: vm.list.length,
                Text: "Add " + addCount
            });
            addCount++;
            //force a refresh of vm.list
        }
    };
    var app = angular.module('myApp', []);
    app.controller('Controller1', c1);
})();
<style> </style> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.min.js"></script>
<div ng-app="myApp">
    <div ng-controller="Controller1 as vm">
        <p>
            <input type="button" ng-click="vm.AddnRefresh();" value="Add" />
        </p>
        <div ng-repeat="l in ::vm.list">{{::l.Text}}</div>
        <p></p>
        <div>LOTS of other stuff going on causing digest updates so really don't want to update list unless "Add" is called"</div>
    </div>
</div>

我参加聚会迟到了,但我还是要参加。

我已经在一个通知模块上工作了一段时间,它终于达到了1.0.0的状态,我觉得我可以开始推荐它了

角度绑定通知程序

你可以通过两种方式使用它;

  1. 为单个属性设置观察程序以更新多个绑定
  2. 手动$broadcast事件以刷新一次性绑定

我认为#2将是实现你所追求的最好的方式,这将是这样的:

<input type="button" ng-click="vm.AddnRefresh();" value="Add" />
<div ng-repeat="l in :refresh:vm.list">
  {{::l.Text}}
</div>

请注意在一次性冒号之间添加的refresh。这是想要触发数据刷新时将使用的key

您现在所需要做的就是更新AddnRefresh方法,如下所示:

vm.addnRefresh = function () {
  /** original implementation **/
  $scope.$broadcast('$$rebind::refresh'); // where 'refresh' is the key used in the view. 
};

$$rebind::是角度绑定通知程序使用的内部事件命名空间

现在,您的视图已更新。


这里有一个jsBin展示了两种更新方式(1$watch&manual$broadcast)。

如果重新创建父DOM元素,Angular将重新渲染视图。您可以使用ng-if、scope变量和$timeout服务的组合来实现这一点:

视图:

<div ng-if="!vm.status.reqRefresh">
     <div ng-repeat="l in ::vm.list">{{::l.Text}}</div>
</div>

控制器:

vm.status = {
    reqRefresh : false
};
vm.AddnRefresh = function () {
    vm.list.push({
        Id : vm.list.length,
        Text : "Add " + addCount
    });
    addCount++;
    //force a refresh of vm.list
    vm.status.reqRefresh = true;
    $timeout(function () {
        vm.status.reqRefresh = false;
    });
}

请在此处查看更新的小提琴:http://jsfiddle.net/karank007/e4nexvay/143/

您必须使用$scope才能查看更新后的视图。我刚刚将vm添加到Scope中。这是代码:

  (function () {
    var c1 = function Controller1($scope) {
       $scope.vm = this;
        var addCount = 1;
        $scope.vm.list = [{
            Id: 1,
            Text: "Blue One"
        }, {
            Id: 2,
            Text: "Blue Two"
        }, {
            Id: 3,
            Text: "Blue Three"
        }];
       $scope.vm.AddnRefresh = function () {
            $scope.vm.list.push({
                Id: $scope.vm.list.length,
                Text: "Add " + addCount
            });
            addCount++;
            //force a refresh of vm.list
        }
    };
    var app = angular.module('myApp', []);
    app.controller('Controller1', c1);
})();

您还必须删除:::

<div ng-app="myApp">
    <div ng-controller="Controller1 as vm">
        <p>
            <input type="button" ng-click="vm.AddnRefresh();" value="Add" />
        </p>
        <div ng-repeat="l in vm.list">{{::l.Text}}</div>
        <p></p>
        <div>LOTS of other stuff going on causing digest updates so really don't want to update list unless "Add" is called"</div>
    </div>
</div>