splincodewd
@splincodewd
Developer

Как запустить перерисовку на Angular, если изменился родительский объект?

Я использовал сервис для связки компонентов

storageService.js
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;

};


В родительском компоненте, я указывал:
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] 
};


Все элементы в DOM строились на таком основании:

<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>


И когда я через кнопки (+) спокойно добавлял в storageService элементы, Angular спокойно видел изменения в $ctrl.storage.structure.item

и прочее

Но когда мне потребовалось делать сохранение проекта в файл, а там я сохранял как JSON.stringify целый сервис

Потом я уже не смог его использовать при открытие проекта

новый метод в 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)
      }

    }


Условно, я хотел заметить свой storageService другим, и чтобы Angular на основании этого сделал перерасчет, но он этого не делает!
  • Вопрос задан
  • 1042 просмотра
Решения вопроса 1
@SuperOleg39ru
Front-end разработчик
Добрый день.

Вам нужно сделать сервис storageService полноценной моделью.

То есть, описываете свойства модели, и методы, что бы получать и изменять эти свойства.
Простой пример, используя систему событий Angular:
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);
    });
  }
}


И в контроллере подписываемся на модель:
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();
    })
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы