One time binding: update model and re-render view

后端 未结 2 2017
庸人自扰
庸人自扰 2020-12-31 07:59

I was wondering if possible, using angular one time binding, to completely re-render the view/template after a model update, also by recompiling the template. For instance,

相关标签:
2条回答
  • 2020-12-31 08:24

    Depending on what you are after, I would recommend one of two solutions:

    • Get angular-bind-notifier.
      • Does not recompile your template, only refreshes the bound values.
    • Get kcd-recompile.
      • Recompiles the template along with the bound values.

    I'm the author of the former, and the big difference between it and other solutions is the choice of hooking into the $parse service.

    As such, you can use the introduced {{:refreshkey:expression}}/:refreshkey:expression syntax in most (if not all) areas of Angular where an expression is accepted.


    In your case, the implementation could look something like this:

    js

    angular.module('app', []).controller('AppCtrl', function($scope) {
      $scope.items = [
          {id: 1},
          {id: 2},
          {id: 3}
      ];
    
      $scope.addAndRefresh = function() {
          $scope.items.push({id: 4});
          /**
           * '$$rebind' is the internal namespace used by angular-bind-notifier.
           * 'refresh' is the refresh key used in your view.
           */
          $scope.$broadcast('$$rebind:refresh');
      };
    });
    

    markup

    <!-- HTML template -->
    <div ng-repeat="item in :refresh:items">
        {{::item.id}}
    </div>
    <button ng-click="addAndRefresh()">Add</button>
    

    Or, if you wanted something semi-dynamic

    js

    angular.module('app', []).controller('AppCtrl', function($scope) {
      $scope.items = [
          {id: 1},
          {id: 2},
          {id: 3}
      ];
    
      $scope.add = function() {
          $scope.items.push({id: 4});
      };
    });
    

    markup

    <!-- HTML template -->
    <div bind-notifier="{ refresh: items.length }">
      <div ng-repeat="item in :refresh:items">
          {{::item.id}}
      </div>
    </div>
    <button ng-click="add()">Add</button>
    

    Check out the README and this jsBin for some usage examples.

    0 讨论(0)
  • 2020-12-31 08:40

    I was trying to figure out some way to do this elegantly as well. I wish there was something built into the framework to refresh one-time bindings. All I came up with is using ngIf to remove the element I wanted to refresh and the add it back.

    Here's a demo. Click the Add Item button, you'll see that the list does not refresh due to the one-time binding on the repeat. Check the refresh values and click again, and the items will be updated:

    var app = angular.module('demo', []);
    
    app.controller('RefreshCtrl', function($scope, $timeout) {
      var counter = 4;
    
      $scope.visible = true;
    
      $scope.items = ['Item1', 'Item2', 'Item3'];
    
      $scope.addItem = function() {
    
        if ($scope.refresh) {
          $scope.visible = false;
        }
    
        $scope.items.push('Item' + counter);
    
        counter++;
    
        $timeout(function() {
          $scope.visible = true;
        });
      };
    
    });
    <script src="https://code.angularjs.org/1.3.17/angular.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    
    <div ng-app="demo" ng-controller="RefreshCtrl" class="container">
      <button class="btn btn-default" ng-click="addItem()">Add Item</button>
      <input type="checkbox" ng-model="refresh" />Refresh Values
      <div ng-if="visible">
        <h3 ng-repeat="item in ::items">{{item}}</h3>
      </div>
    
      <p>Items Array: {{items}}</p>
    </div>

    0 讨论(0)
提交回复
热议问题