M
M
Maxim Ivanov2016-12-12 14:24:10
Angular
Maxim Ivanov, 2016-12-12 14:24:10

How to trigger a redraw in Angular if the parent object has changed?

I used a service to bundle
storageService.js components

export default function (){

  let service = {

    start: false, // запущена ли отрисовка
    ye: 10, // условные единицы
    kq: 1,
    kF: 1,

    base: {
      A: 100, // A
      L: 10, // L
      q: false
    },

    structure: {
      item: [], // KernelList
      F: [],
      leftSealing: false, // заделка слева
      rightSealing: false // заделка
    }
  };

  return service;

};

In the parent component, I specified:
class AppController {

  /**
   * [инициация структуры приложения]
   * @param  {Object} $rootScope     [глобальная область видимости приложения]
   * @param  {Object} storageService [хранимая информация о приложении]
   */
  constructor($rootScope, $scope, storageService){
        this.storage = storageService;
        this._$rootScope = $rootScope;
        this._$scope = $scope;
  }

    /**
     * [добавление стержня]
     */
    addKernelBlock(){

        let storageService = this.storage;

        // первый старт приложения
        this.storage.start = true;

        // добавление первого стержня
        this.storage.structure.item.push(
          angular.copy(storageService.base)
        );

    }

}

export const AppComponent = {
  template: require("./app.html"),
  controller: ['$rootScope', '$scope', 'storageService', AppController] 
};

All elements in the DOM were built on this basis:
<div id="graphs" ng-if="$ctrl.storage.start">
          <kernel ng-repeat="kernel in $ctrl.storage.structure.item track by $index" 
          		  index="$index" 
          		  structure="$ctrl.storage.structure.item"
          		  storage="$ctrl.storage"></kernel>
        </div>

And when I calmly added elements to storageService through the buttons (+), Angular calmly saw changes in $ctrl.storage.structure.item
and so on.
But when I needed to save the project to a file, and there I saved the whole service as JSON.stringify
Then I could no longer use it when opening the project
a new method in the AppController
/**
     * Открытие проекта
     * @return {[type]} [description]
     */
    openProject(){
      let $scope = this._$scope;
      let $rootScope = this._$rootScope;
      let storageService = this.storage;

      try {

        dialog.showOpenDialog(function (fileNames) {

          if (fileNames === undefined) return;

          var fileName = fileNames[0];

          fs.readFile(fileName, 'utf-8', function (err, data) {
            storageService = JSON.parse(data); // тут я заменяю на новый объект, но Angular не реагирует
            
            // не помогло
            $scope.$apply();
            $rootScope.$apply();
            
          });

         }); 

      } catch (e){
        alert(e)
      }

    }

Conventionally, I wanted to notice my storageService in a different way, and for Angular to recalculate based on this, but it does not!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Oleg Drapeza, 2016-12-13
@splincodewd

Good afternoon.
You need to make the storageService a fully fledged model.
That is, you describe the properties of the model, and methods to get and change these properties.
A simple example, using Angular's event system:

export default class StorageService {
  constructor($rootScope) {
    'ngInject';
    this.$rootScope = $rootScope;
    this._model = {};
  }

  getModel() {
    return this._model;
  }

  setModel(newModel) {
    this._model = newModel;
    // вызываем событие Сервис изменился, при каждом изменении модели
    this.$rootScope.$broadcast('storageServiceChange');
  }

  loadFromFile(fileName) {
    fs.readFile(fileName, 'utf-8', (err, data) => {
        let newModel = JSON.parse(data);
        this.setModel(newModel);
    });
  }
}

And in the controller we subscribe to the model:
class AppController {
  constructor($rootScope, $scope, storageService) {
        'ngInject';
        this.storage = storageService;
        this.$rootScope = $rootScope;
        this.$scope = $scope;
        this.model = {};    
  }
  
  $onInit() {
    this.storage.loadFromFile('storage.txt');
    // подписываемся на событие Сервис изменился, и обновляем модель
    this.$rootScope.$on('storageServiceChange', () => {
        this.model = this.storage.getModel();
    })
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question