Как связать объект, возвращенный фабрикой, с методом элемента?

Я изучаю, как использовать angular, и я решил разделить некоторый код на его собственный модуль, чтобы сохранить мой основной файл javascript более чистым. У меня все работает, кроме обязательной части. До того, как я разделил его, в моем HTML-файле был элемент, использующий ngStyle и у меня была переменная в моей области. Я бы позвонил $scope.$apply(function () { $scope.styles = { width: xxx }; }) когда бы я ни установил переменную в моей области видимости, и элемент обновится.

Когда я удалил все из своего кода и разделил его на фабрику и директивы, я не мог понять, как сделать то же самое. Я в основном закончил с кодом ниже, и все работает, кроме eleСтиль тега не обновляется.

Я хотел использовать переменные для хранения значений и генерирования объекта стилей, чтобы мне не пришлось выполнять дополнительную работу самостоятельно, правильно ли я справился? Если так, как я могу убедиться, что элемент обновляется, когда myFactory"s size переменные изменения? Если нет, что было бы лучшим способом справиться с этим?

angular.module('test').factory('myFactory', function ($) {
    var size = 0;

    return {
        setSize: function (value) {
            size = value;
        },
        styles: {
            width: size + "px"
        }
    };
});

angular.module('test').directive('testDirective', ['myFactory', function (myFactory) {
    return {
        restrict: 'EA',
        link: function (scope, ele) {
            ele.css(myFactory.styles);
        }
    };
}]);

3 ответа

Решение

Проверьте рабочую демоверсию: JSFiddle (Объединяя ответ charlietfl и Exo).

На заводе поменяй styles быть объектом:

angular.module('test', [])
    .factory('myFactory', function () {
    var styles = {
        width: 100 + 'px'
    };

    return {
        setSize: function (value) {
            styles.width = value + 'px';
            console.log(styles);
        },
        styles: styles
    };
})

затем $watch объекты в директиве link функция:

scope.$watch(function () {
    return myFactory.styles;
}, function (newValue) {
    ele.css(newValue);
}, true);

Функция ссылки запускается только один раз, когда директива добавляется в DOM. Я предполагаю, что вы намеренно не хотите добавлять элементы в DOM с помощью этой директивы, поэтому я бы предложил попробовать что-то вроде:

angular.module('test').directive('testDirective', ['myFactory', function (myFactory) {
  return {
    restrict: 'EA',
    link: function (scope, ele) {
      scope.$watch(function () {
        return myFactory.styles;
      }, function (newValue) {
        ele.css(newValue);
      }, true);
    }
  };
}]);

Ваш size переменная является примитивом, поэтому ваше свойство width не будет обновляться при его изменении. styles.width значение будет только тем, что есть, когда фабрика инициализирована.

Измените функцию setSize() для фактического обновления styles.width

 setSize: function (value) {
    this.styles.width = value + 'px';
  }

Теперь все области, которые совместно используют это свойство, также будут обновлены.

Другие вопросы по тегам