0

I'm new to angualarjs and just start to build a page using angularjs 1.5 component. I'm trying to understand the following example from pluralsight. Does angularjs extended javascript with partial application/currying and others?

movie-rating.component.html: function model.setRating() is passed with an object with property of value.

<span ng-repeat="entry in model.entries track by $index">
    <span ng-click="model.setRating({ value: $index + 1})" class="glyphicon {{entry}}">
    </span>
</span>

movie-rating.component.js: the setRating is bound using "&".

module.component("movieRating", {
    templateUrl: "/ps-movies/movie-rating.component.html",
    bindings: {
        value: "<",
        max: "<",
        setRating: "&"
    },

movie-list.component.html: However, when using the component, the set-rating is assigned a function with two paramters model.setRating(movie, value)? And movie is actually a value from <tr ng-repeat="movie in model.movies">? but value?

<tr ng-repeat="movie in model.movies">
    <td>{{movie.title}}</td>
    <td>{{movie.length}}</td>
    <td>
      <movie-rating value="movie.rating" max="5" set-rating="model.setRating(movie, value)">
      </movie-rating>
    </td>

movie-list.component.js: And in the following code model.setRating = function(movie, rating), there is no parameter that supposes to an object with property of value?

function controller($http) {
    var model = this;
    model.movies = [];

    model.$onInit = function() {
        fetchMovies($http).then(function(movies) { model.movies = movies; });
    };

    model.upRating = function(movie) { if(movie.rating < 5) { movie.rating += 1; } };
    model.downRating = function(movie) { if(movie.rating > 1) { movie.rating -= 1; } };

    model.setRating = function(movie, rating) { // rating is int, and movie is string
        movie.rating = rating;
    };

1 Answer 1

1

In AngularJS, the expressions bound by & are not executed in parameter order. Instead, when you execute a function bound like this, you have to execute it with an object. Let's take your example,

<movie-rating set-rating='model.setRating(movie, value)'></movie-rating>

Now, your movie-rating component will receive a setRating function and assign it to its controller. When you execute $ctrl.setRating() inside of the movieRating controller, Angular is going to expect you to pass it an object like

{ movie: 0, value: 0 }

it will then map these values to the parameter order specified in the string passed to set-rating; in other words, Angular will take model.setRating(movie, value) and work out that it actually needs to pass in the value of the movie key from the passed object to the first parameter and the value object to the second parameter.

So, when you click your span inside of movie-rating, it will call setRating({ value: $index }). It will leave movie undefined, so the parent function, movieList.setRating will receive the parameters (undefined, $index).

Note that all of this expression binding behaviour (where the names of movie and value inside of the set-rating expression are preserved) only applies to the template. This is why in JavaScript code you see that Angular does not fall over.


To basically tldr this, when you use value names in a function binding in the template, Angular will unpack an object passed to an invocation of the function and match up the parameters via name. It will only do this for & bindings, and only unpack js objects to & bindings (which have to be defined in HTML). It will not unpack JS objects to regular JS functions (which makes sense - the HTML bindings won't be mangled, but JS variable names will be mangled at runtime; this is why you need to use $inject or array syntax for dependency injection in Angular)

let me know if I can explain this any clearer

Sign up to request clarification or add additional context in comments.

1 Comment

here is some more readings from angularjs.org site: docs.angularjs.org/api/ng/service/$compile#-scope-, see paragraph starting with '& or &attr - provides a way to execute an expression in the context of the parent scope.'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.