Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngualrJS 1.3 manually update binding with one time binding

I want to use one-time binding in my view {{::vm.list}}. That's all working well and good. However on a button click I want vm.list to refresh.

I can't seem to figure out how to manually trigger vm.list to update. Perhaps one time binding is not the answer?

here is a jsfiddle boilerplate example: 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>
like image 419
user1949561 Avatar asked Feb 23 '15 14:02

user1949561


People also ask

Does AngularJS use one-way data-binding?

Angular is known for its powerful two-way data-binding, but with the new release of AngularJS 1.5, we've got one-way data binding (one-directional) binding capabilities inside our Components and Directives.

What is one-way binding in AngularJS?

One-way binding via {{..}} means that AngularJS only needs to watch your $scope, but won't be on the lookout for changes to the value from the DOM.

Does AngularJS support two-way binding?

Two-way BindingData binding in AngularJS is the synchronization between the model and the view. When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well.

What is :: In AngularJS?

It's used to bind model from your controller to view only. It will not update your controller model if you change this from your view. It means it's used to achieve one time binding. Example. angular.


1 Answers

I'm late to the party but I'll pitch in nevertheless.

I've been working on a notifier module for some time now and it's finally reached a 1.0.0 state where I feel I can start recommending it.

angular-bind-notifier

You could use this in two ways;

  1. Setup a watcher for a single property to update multiple bindings.
  2. $broadcast events manually to refresh a one-time binding.

I reckon #2 would be the best way to fulfill what you're looking for and that would go something like this:

<input type="button" ng-click="vm.AddnRefresh();" value="Add" />

<div ng-repeat="l in :refresh:vm.list">
  {{::l.Text}}
</div>

Notice the refresh that's been added between your one-time colons. This is the key you will utilise when wanting to trigger a refresh of the data.

All you need to do now is to update the AddnRefresh method like so:

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

$$rebind:: is the internal event namespace used by angular-bind-notifier.

And there you go - your view is now updated.


Here's a jsBin showcasing both ways of updating (1 $watcher & manual $broadcast).

like image 133
Kasper Lewau Avatar answered Sep 27 '22 19:09

Kasper Lewau