Переменная $scope не изменяется в контроллере при изменении с помощью директивы

Я пробовал всеми способами (сохраняя область видимости false и т. д., но не имея возможности изменить область действия в контроллере), я что-то упустил.

директива:

angular.module("ui.materialize.inputfield", [])
        .directive('inputField', ["$timeout", function ($timeout) {
            return {
                transclude: true,
                scope: {},
                link: function (scope, element) {
                    $timeout(function () {
                        Materialize.updateTextFields();

                        // The "> > [selector]", is to restrict to only those tags that are direct children of the directive element. Otherwise we might hit to many elements with the selectors.

                        // Triggering autoresize of the textareas.
                        element.find("> > .materialize-textarea").each(function () {
                            var that = $(this);
                            that.addClass("materialize-textarea");
                            that.trigger("autoresize");
                            var model = that.attr("ng-model");
                            if (model) {

                                scope.$parent.$watch(model, function (a, b) {

                                    if (a !== b) {
                                        $timeout(function () {

                                            that.trigger("autoresize");
                                        });
                                    }
                                });
                            }
                        });

                        // Adding char-counters.
                        element.find('> > .materialize-textarea, > > input').each(function (index, countable) {
                            countable = angular.element(countable);
                            if (!countable.siblings('span[class="character-counter"]').length) {
                                countable.characterCounter();
                            }
                        });
                    });
                },
                template: '<div ng-transclude class="input-field"></div>'
            };
        }]);

а вот мой взгляд

<div ng-controller="Example Controller"
<div input-field class="col l3">
    <input type="text" ng-model="class1" length="150">
    <label>Class</label>
    {{class1}}
</div>
{{class1}}
</div>

Я вижу, что меняется только class1 области действия директивы, но не последний class1,

если я инициализирую свой контроллер с помощью $scope.class1 = 9, меняется только первый class1, но не второй class1. Может ли кто-нибудь помочь мне в решении проблемы


person vanquishers    schedule 02.07.2016    source источник


Ответы (3)


Решение вашей проблемы заключается в использовании синтаксиса controllerAs в вашем представлении.

<div ng-controller="ExampleController as ctrl"
    <div input-field class="col l3">
        <input type="text" ng-model="ctrl.class1" length="150">
        <label>Class</label>
        {{ ctrl.class1 }}
    </div>
    {{ ctrl.class1 }}
</div>

В вашем контроллере вместо того, чтобы прикреплять свойства к $scope, вы прикрепляете его непосредственно к экземпляру вашего контроллера.

angular
    .module('app')
    .controller('ExampleController', function () {
        var vm = this; // vm stands for View-Model and is reference to current controller instance

        vm.class1 = 'some class';
    });

Это гарантирует, что вы везде имеете дело с одним и тем же свойством контроллера class1.

Чтобы понять, почему это работает, прочитайте эту документацию о том, как область видимости работает в Angular.

Понимание областей

person Prashant    schedule 02.07.2016
comment
если переменная области видимости изменяется динамически, мы можем привязать ее к представлению с помощью $watch или $apply, но что мы можем сделать, чтобы привязать представление {{ctrl.variable}} к новому значению, когда оно динамически изменяется в контроллере? - person vanquishers; 02.07.2016
comment
Angular прикрепляет экземпляр контроллера к $scope с заданным псевдонимом в качестве свойства $scope. Итак, $scope.ctrl в моем примере — это экземпляр контроллера. Затем вы можете $watch, как обычно, просматриваете любое свойство $scope. $scope.$watch('ctrl.class1', someListenerFunction); - person Prashant; 02.07.2016
comment
stackoverflow.com/questions/38160209 / вы можете помочь в этом - person vanquishers; 02.07.2016

Ваша директива работает с div, на котором она установлена, а второй class1 находится за пределами этого div и, следовательно, вне области действия вашей директивы.

person Maarten    schedule 02.07.2016
comment
Я это понял, но как я могу изменить свой код, чтобы он мог изменять переменную вне области действия моей директивы? - person vanquishers; 02.07.2016
comment
@Maarteen, вы можете помочь в этом stackoverflow.com/questions/38160209/ - person vanquishers; 02.07.2016

никогда не используйте модель примитивного типа. всегда используйте с точечным свойством.

изменить ng-модель с класса на form1.class1

person Abhishek Kumar    schedule 02.07.2016
comment
но я считаю, что это не работает для свойств вложенных точек (пример: form1.class1.section вызывает ту же проблему - person vanquishers; 02.07.2016
comment
stackoverflow.com/questions/38160209 / вы можете помочь в этом - person vanquishers; 02.07.2016