Arturs Vancans
Arturs Vancans

Reputation: 4640

How to propogate a changing scope variable through a function in AngularJs?

For example, if I have the following case:

function ACtrl($scope) {
  $scope.title = "Title";
  $scope.funkyString= funkyAndComplexStuff($scope.title);
  function funkyAndComplexStuff(title) {
     /*...*/
     return title;   
  }
}

With html:

<div ng-app>
  <div ng-controller="ACtrl">
    <div>
      {{title}} and length {{funkyString}}
        <input type="text" ng-model='title' />
    </div>
  </div>
</div>

I would like the $scope.funkyString to update every time $scope.title gets changed.

As far as I see I have 2 options:

But both of those sound unndecessarily heavy. Is there anything else I could use to post-process the data as soon as it gets changed?

EDIT:

Modified my example so that people are hopefully less confused.

Upvotes: 1

Views: 61

Answers (5)

Strelok
Strelok

Reputation: 51441

Why not just:

function ACtrl($scope) {
  $scope.title = "Title";
  $scope.funkyAndComplexStuff = function () {
     /*..do stuff with $scope.title..*/
     return $scope.title; // or whatever   
  }
}

With html:

<div ng-app>
    <div ng-controller="ACtrl">
      <div>
        {{title}} and length     {{funkyAndComplexStuff()}}
         <input type="text" ng-model='title' />
      </div>
     </div>
   </div>

Not sure why somebody downvoted, but here is a demo: http://jsfiddle.net/xhdk3f25/1/

Upvotes: 0

Matt Herbstritt
Matt Herbstritt

Reputation: 4862

ng-change could be a simple solution depending on the element to which your title model is bound. If it's an input like in the example this might could work:

app.controller('MainCtrl', function($scope) {
  $scope.title = "Title";

  $scope.funkyAndComplexStuff = function(title) {
     /*...*/
     $scope.funkyString = title.length;   
  }
});

...

<body ng-controller="MainCtrl">

     {{title}} and length {{funkyString}}
     <input type="text" ng-model='title' ng-change="funkyAndComplexStuff(title)" />

</body>

Upvotes: 0

ssilas777
ssilas777

Reputation: 9804

I would try something like this, so it can handle changes to $scope.title from other fields of code also

<div ng-controller="ACtrl">
    <div>
      {{title}} and length {{ funkyAndComplexStuff(title) }}
        <input type="text" ng-model='title' />
    </div>
  </div>

Upvotes: 2

Thom-x
Thom-x

Reputation: 866

Like ssilas777 and Charlie S and you said you can use $watch, custom $filter or function in $scope

But for me it's complicated to maintain code with function linked to the view. I prefere using $watch because all the processing is in the controller and only $scope.numberOfChars is present in the view.

If you use this many time, I would suggest you to create a custom filter.

angular.module('app',[])
.controller('ACtrl',
function ($scope) {
  $scope.title = "Title";
  getNumberChars($scope.title);
  function getNumberChars(title) {
     $scope.numberOfChars = title.length;   
  };
  
  $scope.getNumberChars = function() {
     return $scope.title.length;   
  };
  
  $scope.$watch('title',getNumberChars);
})
.filter('customFilter', function() {
  return function(input) {
    return input.length;
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="ACtrl">
    <div>
      {{title}} and length {{numberOfChars}} or {{title.length}} or {{getNumberChars()}} or {{title | customFilter}}
        <input type="text" ng-model='title' />
    </div>
  </div>
</div>

Upvotes: 0

Charlie Schliesser
Charlie Schliesser

Reputation: 8227

You could do title.length as @ssilas777 has suggested. You can also set the $scope variable to be a function. As I understand it, the function will be called during the scope's $digest cycle, which will fire when any bound model changes. See this plunkr: http://plnkr.co/edit/9xspXj5ND8seEX2LNeMe?p=preview

See this HTML:

<input type="text" ng-model="title" />
Num chars: <span ng-bind="numCharsInTitle()"></span>

and the JS:

$scope.title = "The Title";
$scope.numCharsInTitle = function() {
  return $scope.title.length;
}

Upvotes: 2

Related Questions