Angular 1.5 component bindings, $ onChanges hook & ui-router allows

EDIT: I reformulated this question here: angular 1.5 component, ui-router resolution, $ onChanges life cycle

I will illustrate my question with three consecutive examples.

In the first, the so-called external component has a myData object, which has a name field. This object is passed to the internal component using one-way binding. The external component provides two methods for updating its object: a change, which changes the value of the name field, and replaces it with a new object. When a change is invoked, the object visible in the internal component is updated because one-way binding is done by reference. When replace is called, the object seen in the internal component is also updated because the one-way snapping monitors the reference modification and the $ onChanges hook is called. Everything is fine here :-)

angular
.module('app', [])

.component('outer', {
    controller: function () {
      this.myData = {
        name: 'initial'
      };
      this.modify = (value) => { this.myData.name = value; };
      this.replace = (value) => { this.myData = { name: value }; };
    },
  template: `
    <p> outer value : {{ $ctrl.myData.name }} </p>
    <input type="text" ng-model="value">
    <button ng-click="$ctrl.modify(value)"> modify object </button>
    <button ng-click="$ctrl.replace(value)"> replace object </button>
    <hr>
    <inner my-data="$ctrl.myData"></inner>
  `
})

.component('inner', {
  bindings: {
    myData: '<'
  },
  controller: function () {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
  },
  template: `
    <p> inner value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
  `
});

(https://plnkr.co/edit/uEp6L4LuWqTJhwn6uoTN?p=preview) myData, - ui-router. - , .

angular
.module('app', ['ui.router'])

.config(($urlRouterProvider, $stateProvider) => {
    $urlRouterProvider.otherwise('/');

    $stateProvider
    .state('root', {
      url: '/',
      component: 'outer',
      resolve: {
        myData: () => ({ name: 'initial' })
      }
  });
})

.component('outer', {
  bindings: {
    myData: '<'
  },
  controller: function () {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
    this.modify = (value) => { this.myData.name = value; };
    this.replace = (value) => { this.myData = { name: value }; };
  },
  template: `
    <p> outer value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
    <input type="text" ng-model="value">
    <button ng-click="$ctrl.modify(value)"> modify object </button>
    <button ng-click="$ctrl.replace(value)"> replace object </button>
    <hr>
    <inner my-data="$ctrl.myData"></inner>
  `
})

.component('inner', {
  bindings: {
    myData: '<'
  },
  controller: function () {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
  },
  template: `
    <p> inner value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
  `
});

(https://plnkr.co/edit/nr9fL9m7gD9k5vZtwLyM?p=preview) , myData . ui-router . . . , $onChanges , , .

angular
.module('app', ['ui.router'])

.factory('DataService', () => {
  let data = { name: 'initial' };
  return {
    getData: () => data,
    modify: (value) => { data.name = value; },
    replace: (value) => { data = { name: value }; }
  }
})

.config(($urlRouterProvider, $stateProvider) => {
    $urlRouterProvider.otherwise('/');

    $stateProvider
    .state('root', {
      url: '/',
      component: 'outer',
      resolve: {
        myData: (DataService) => DataService.getData()
      }
  });
})

.component('outer', {
  bindings: {
    myData: '<'
  },
  controller: function (DataService) {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
    this.modify = (value) => { DataService.modify(value); };
    this.replace = (value) => { DataService.replace(value); };
  },
  template: `
    <p> outer value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
    <input type="text" ng-model="value">
    <button ng-click="$ctrl.modify(value)"> modify object </button>
    <button ng-click="$ctrl.replace(value)"> replace object </button>
    <hr>
    <inner my-data="$ctrl.myData"></inner>
  `
})

.component('inner', {
  bindings: {
    myData: '<'
  },
  controller: function () {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
  },
  template: `
    <p> inner value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
  `
});

?

: . , , ( ) $onChanges ().

: (https://plnkr.co/edit/DZqgb4aIi09GWiblFcmR?p=preview), , , , . : $onChanges , , , ? ?

angular
.module('app', ['ui.router'])

.factory('DataService', () => {
  let data = { name: 'initial' };
  return {
    getData: () => data,
    modify: (value) => { data.name = value; },
    replace: (value) => { data = { name: value }; }
  }
})

.component('editor', {
  controller: function (DataService) {
    this.modify = (value) => { DataService.modify(value); };
    this.replace = (value) => { DataService.replace(value); };
  },
  template: `
    <input type="text" ng-model="value">
    <button ng-click="$ctrl.modify(value)"> modify object </button>
    <button ng-click="$ctrl.replace(value)"> replace object </button>
  `
})

.config(($urlRouterProvider, $stateProvider) => {
    $urlRouterProvider.otherwise('/');

    $stateProvider
    .state('root', {
      url: '/',
      component: 'consumer',
      resolve: {
        myData: (DataService) => DataService.getData()
      }
  });
})

.component('consumer', {
  bindings: {
    myData: '<'
  },
  controller: function () {
    this.nbOnChangesCalls = 0;
    this.$onChanges = (changes) => { this.nbOnChangesCalls++; }
  },
  template: `
    <p> value : {{ $ctrl.myData.name }} (nb onChanges calls : {{ $ctrl.nbOnChangesCalls }}) </p>
  `
});

$onChanges :

this.$onChanges = (changes) => {
  if (changes.myData) this.myData = Object.assign({}, this.myData);
  this.nbOnChangesCalls++;
}

( , ), $onChanges ( !) .

+4

Source: https://habr.com/ru/post/1648894/


All Articles