Data binding Controller-Service: works for objects

2019-07-04 21:31发布

问题:

Why are the data synced for the int in json_var and not for the int?

myService.json_var is updated when $scope.json_var changes. myService.int_var is not updated when $scope.int_var changes.

var myApp = angular.module('myApp', []);

myApp.factory('myService', [
  function() {
     return {
        json_var : {val:17},
        int_var : 36
     }

     }
  ]);


myApp.controller('myCtrl', [ '$scope',  'myService', 
  function ($scope, myService)
  {
     $scope.json_var = myService.json_var; // doing this myService.json_var is updated when $scope.json_var changes
     $scope.int_var = myService.int_var; // no sync for int

     $scope.deb = function()
     {
        console.log($scope.int_var);
        console.log( myService.int_var);

        console.log($scope.json_var.val);
        console.log( myService.json_var.val);
     }
  }
] );

https://gist.github.com/SebSept/8ddcaad130ef9c091bd0

回答1:

In JavaScript, composite types (objects, arrays) are passed by reference (copy of a reference, to be precise), and primitives (strings, numbers, booleans) are passed by value.

36 is a primitive. When you pass your primitive from your service (myService.int_var) into your controller ($scope.int_var) the 36 is passed by value. When you change $scope.int_var to 42 the myService.int_var variable will not reflect the change (this is per language design).

On the other hand, myService.json_var is a composite. When you pass myService.json_var to $scope.json_var, a reference to the myService.json_var object is passed by value to the $scope.json_var variable. When you change something inside that variable (e.g. if you change json_var.val to 18), the change will be reflected inside the myService.json_var object as well, so myService.json_var.val will equal 18 as well.

tl;dr Make sure there's always a dot "." somewhere when you're passing things around in Angular.



回答2:

Numbers aren't mutable. Binding to numbers sucks, cause as soon as the number changes, you lost reference what you are bound, as the reference to the old number is lost (to you). If you are going to reference numbers that will be changing, you have to place them in an object and then bind to the object (cause objects are mutable).

When learning Angular, I ran into this same frustration. I think that a lot of people do.