Что происходит, когда я использую .scope() в angularjs?

#javascript #angularjs #angularjs-directive #angularjs-scope

#javascript #angularjs #angularjs-директива #angularjs-область

Вопрос:

Не мог бы кто-нибудь объяснить, что происходит, когда я использую .scope() внутри директивы?

У меня есть директива, которая назначается для создания сетки квадратов. При загрузке я бы хотел, чтобы эти квадраты были интерактивными, поэтому я назначил

 ng-click="disabled || add($index)"
  

и затем link: function () {} я запускаю:

 scope.add = function (index) {
     scope.disabled = true;
}
  

так что все они становятся отключенными по щелчку.

Затем у меня есть служба, которая принимает индекс одного из полей, на которое нажимается, выполняет некоторую логику, а затем возвращает другие возможные квадраты, которые могут быть интерактивными. Служба возвращает массив индексов, например [2,5,6,7]

Затем я беру этот массив, перебираю его и назначаю эти поля интерактивными через их индекс:

 for (var x = 0; x < arr.length; x  ) {
    var nScope = el.children().eq(arr[x]).scope();
    nScope.disabled = false;
}
  

Впоследствии, когда щелкается другой из вышеперечисленных элементов, оригинал scope.disabled = true; игнорируется, а те, которые я настраиваю выше в цикле, чтобы быть интерактивными, остаются интерактивными… Почему это? Что происходит, когда я запускаю .scope() выше, и как мне обновить сетку, чтобы она снова не была интерактивной, пока служба не вернется с более возможными ходами?

И, конечно, если есть более правильный способ сделать это, пожалуйста, поделитесь.

Редактировать:

Добавление дополнительного кода по запросу в комментариях:

Шаблон HTML:

 <div 
    class="cell" 
    ng-click="disabled ||  addItem($index)" 
    ng-disabled="disabled" 
    ng-repeat="cell in ngModel.grid track by $index">{{item}}</div>
  

Настройки для директивы следующие:

 return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
        ngModel: '='
    },
    templateUrl: 'scripts/grid/grid.html',
    link: function () {
        //code above goes here
    }
}
  

Служба выполняет различные функции, одна из которых заключается в предоставлении того, какие возможные объекты можно щелкнуть, на основе индекса объекта, на который был сделан первоначальный щелчок. Для целей этого вопроса я опустил код службы, поскольку моя единственная проблема пока заключается в том, чтобы точно выяснить, что делает .scope() и как я могу использовать это в своих интересах.

Комментарии:

1. Нам нужно больше кода, каковы ваши начальные настройки моделей? Есть ли какие-либо атрибуты, передаваемые директивой? Какова цель службы? Я не думаю, что такое общее имя, как «отключено», является хорошей идеей для переменной области видимости. Это должен быть атрибут: a $scope.box = {статус: «отключено»}. Что касается вашей ошибки, вам, вероятно, нужно то, что называется «изолированная область» для вашей директивы. Погуглите несколько руководств по директивам.

2. Спасибо за ваш ответ, я добавил еще немного кода к сообщению.

Ответ №1:

Это не дает полного ответа на ваш вопрос, но может быть подходом, на который вы могли бы опираться.

Посмотрите на эту скрипку: http://jsfiddle.net/HB7LU/4553 /

 var myApp = angular.module('myApp',[]);


myApp.service('myService', function() {
    return{
        saveBox: function(id)
        {
        alert('gonna update box with id: ' id);
        }
    }
});


myApp.directive('boxgenerator', ['myService', function(myService) {
    return {
        template: '<div class="box {{status}} -  {{id}}">{{status}}</div>',
        scope:{
            id: '@id',
            status: '@status'
            },
    link : function(scope, element, attrs) 
        {
            element.bind("click",function(){
               save = myService.saveBox(scope.id);
               scope.status = 'disabled'; 
               scope.$apply();
            });
        }
    }
}]);


function MyCtrl($scope) {
    $scope.boxes = [];
    $scope.box = { status: 'enabled' };

    for (i = 0; i < 9; i  )
    {
       $scope.boxes.push($scope.box);
    }
}
  

Возможно, из этого вы можете провести рефакторинг более простым способом.

Комментарии:

1. Спасибо, что нашли время написать все это и привести пример. Каков был бы наилучший способ обновить то, что у вас есть, отключив все поля (а не только тот, на который вы нажимаете) при первом нажатии, а затем сразу после этого включить определенное (случайное) поле? Я спрашиваю, потому что область видимости изолирована (как и должно быть), так каков был бы правильный подход для доступа к глобальной области видимости в директиве и отключения всех полей после этого щелчка. И как только это произойдет, каким будет правильный способ случайного включения другого?

2. Пожалуйста, директивы, пожалуй, самая сложная часть AngularJS, и я все еще учусь сам. На самом деле, я немного научился при написании примера! Для random у вас, вероятно, есть множество ванильных JS-скриптов, которые не могут найти случайную запись в JS-объекте ($scope.boxes ). Что касается начального щелчка, вы можете отслеживать, сколько раз пользователь нажимал, $ broadcast (ing) начальный щелчок в $ rootScope . Должен сказать, трудно понять концепцию вашего приложения… Доступны ли отключенные поля после выбора случайного? Является ли поле включения интерактивным?

3. Да, я тоже пытаюсь разобраться во всем этом. На «очень» базовом уровне, вот пример codepen: codepen.io/anon/pen/vnLdt Забавно, что на выполнение всего вышесказанного в jQuery ушло около 5 минут. Эта угловая интерпретация заняла у меня гораздо больше времени, и все потому, что мне еще предстоит понять область видимости.