#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 минут. Эта угловая интерпретация заняла у меня гораздо больше времени, и все потому, что мне еще предстоит понять область видимости.