Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: force refresh native one-time bindings

Tags:

angularjs

Is there a way to force a refresh on a one-time binding (native one-time binds present in v1.3+ not BindOnce library) without having to recompile the entire DOM node (which is what the kcd-recompile directive seems to be doing)

The following code illustrates my problem:

<span ng-bind="::firstname" refresh-on="firstNameUpdated"></span>

Here I want the content of span to be updated to the current value of $scope.firstname.

The way I imagine the way it would be done is by using the directive refresh-on, which forces a refresh when it receives the event "firstNameUpdated".

like image 791
Yogesh Mangaj Avatar asked Apr 23 '15 13:04

Yogesh Mangaj


2 Answers

Shameless commercial here for something I've been tinkering on.

angular-bind-notifier

Which for your use case would look like this:

<span bind-notifier="{fName:firstName}" ng-bind=":fName:firstName"></span>

Where fName is the eventKey, and firstName is the watched expression.

It works sort of like kcd-recompile (the core idea is the same), but with some main differences;

  • I hook into the $parse service - so as to not recompile the entire DOM node.
  • Support for multiple key:val expressions for rebinding.

With all of that said, I don't see a huge gain in doing this for a single boundValue.

It'd be a better idea (imho) to run a regular {{}} for a single value. You're just trading one $watch for the other here, kcd-recompile and bind-notifier only ever really shines brightly when you have multiple values to refresh occasionally.

like image 126
Kasper Lewau Avatar answered Oct 10 '22 09:10

Kasper Lewau


I had to do this because I was using angular-datatables and I didn't want the data-table to keep refreshing every time a carousel with a 5-second timer changed images on it. But, I also wanted to be able to refresh the table under specific circumstances.

What I did was wrap the entire datatable in an ng-if="data", and I set one-time-bindings to all the ng-repeats in the table (I had more than one. One to dynamically set columns, one for the rows).

Then, when I want to refresh the table, I do this first:

$timeout(function(){
    $scope.$apply(function(){
        $scope.data = null;
    });
});
//Put code to set $scope.data to a new value here

This removes the entire table from the dom before it is re-created. When it is re-created, the one-time-bindings will re-bind. It's a little expensive, but it works.

So that's your answer. If you remove a section of html with a one-time-binding from the DOM with ng-if, and then put it back in, it will re-bind to a new value.

like image 10
Craig Avatar answered Oct 10 '22 10:10

Craig