Идея директивы привязки данных интересна, но это не так, как я бы это сделал, так как я считаю, что вы столкнулись с директивными приоритетными проблемами, а также тем фактом, что она очень нестандартная и сделает ваш код трудным для выполнения для будущих программистов. Есть несколько способов сделать это, поэтому я обсужу 3 разных решения, которые я использовал.
Решение 1
Если вам нужна только один способ связывания данных, самое простое решением является использование сферы угловой х. $ Eval функция на строковом представлении объекта внутри вашей директивы после интерполирования любых простых переменных областей видимости на используя {{}}. Строковое представление даже не должно быть допустимым JSON, так как вы заметите в примере ниже, я не включаю кавычки вокруг ключей объектов.
По мнению:
<div databinding="{one:'first', two:{{scopeVar}}, complex:[1,2, "Hi"]}"></div>
И в JavaScript:
app.directive('databinding', function() {
return{
link: function (scope, elm, attrs) {
console.debug(scope.$eval(attrs['databinding']));
}
}
});
Solution 2
Еще один способ данные решения связывание создать объект параметров внутри и передать его в директиву с использованием «@» (или даже «=»):
В контроллере:
$scope.options = {one: "first, two: "second"};
В представлении:
<div databinding="options"></div>
И в JavaScript:
app.directive('databinding', function() {
return{
scope: {
options: "@" //Can also use = here
},
link: function (scope, elm, attrs) {
console.log(scope.options);
}
}
});
Solution 3
Если вам нужны два пути привязка данных, вам в основном не повезло, так как нет элегантного способа сделать это. ОДНАКО, если вы находитесь на рынке хакерских решений, вы можете выполнить двустороннюю привязку данных с помощью метода, очень похожего на решение 2, но с изменением объекта option.
Вместо объявления объекта опции, содержащего простые примитивные типы данных, такие как строки, создайте в объекте объекта фиктивный объект, который затем объявляете переменные внутри. Таким образом, изменения в переменных области в вашем контроллере также будут реализованы внутри директивы, как показано через таймауты.
Контроллер:
$scope.someScopeVar = "Declared in controller"
$scope.options = {
dummy: {
one: $scope.someScopeVar,
two: "second"
}
}
window.setTimeout(function(){
$scope.someScopeVar = "Changed in controller";
}, 2000)
Вид:
<div databinding="options"></div>
Директива:
app.directive('databinding', function() {
return{
scope: {
options: "=" //You need to use = with this solution
},
link: function (scope, elm, attrs) {
console.log(scope.options.dummy.one); //Outputs "Declared in controller"
window.setTimeout(function(){
console.log(scope.options.dummy.one) //Outputs "Changed in controller"
}, 5000)
}
}
});
Этот метод работает с Java-объекты, проходит по ссылке, тогда как примитивы копируются. При вложении объекта в объект сохраняется привязка данных.
Это будет работать, если бы каждая переменная имела другой атрибут. Я пытаюсь избежать этого. Я хочу отправить все свои данные по одному атрибуту, а затем разделить их. Возможно, перечитайте вопрос, чтобы уточнить. – Spencer