2015-11-20 1 views
4

Это расширение предыдущего вопроса (и подобных вопросов), в котором я спросил, возможно ли иметь атрибут в директиве, разрешить значение передаваться так.Угловая директива - создать новую привязку для двухсторонней и «передать по значению»

<my-directive att>    //Evaluates to true 
<my-directive att="true">   
<my-directive att="false"> 
<my-directive att="51"> 
<my-directive att="51.234"> 
<my-directive att="'john smith'"> 

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

<my-directive att="SomeVariableOnControllerScope"> 

Теперь это не будет работать со стандартным двусторонним связыванием «=». Я пробовал различные попытки, но всякий раз, когда вы пытаетесь изменить что-то внутри своей директивы, он пытается записать его обратно в переменную, и если это не соответствующая переменная, вы получаете стандартную ошибку «не назначаемая».

Но кто-то намекнул на то, что можно было бы создать новый тип привязки. Теоретически этот новый тип привязки мог бы смотреть на переданное значение, чтобы увидеть, было ли оно логическим, целочисленным, float или строкой в ​​одинарных кавычках. Если бы это было, это могло бы использовать это и «отключить» двустороннюю привязку, поэтому ничего не получится. Если значение не является переданным, то оно будет делать точно как = и устанавливает двустороннюю привязку.

Я понятия не имею, как это сделать, но, возможно, сможешь его обработать, если дать толчок в правильном направлении. Значение в этом состоит в том, что нам часто приходится выводить HTML с сервера (по причинам SEO), который устанавливает значение и часто не нужно связывать что-то с контроллером. Однако иногда требуется 2 способа привязки.

Итак, в основном я ищу гибрид @ и = привязка, который разумно знает, передается ли значение или имя переменной.

Любые идеи?

+0

Скорее вы можете использовать ** @ operator ** и передать дополнительный атрибут для типа данных. Затем вы можете передать значение в нужный тип данных внутри директивы. – Vivek

ответ

2

1/$ служба синтаксического анализа может разобрать значение и сказать, если это константа или не

https://docs.angularjs.org/api/ng/service/ $ синтаксического

2/Это код, который используется на отдельных областях для двойного пути области видимости привязок:

 var dataBind = function(parentScopeName, scopeName, childScope, parentScope) { 
     if(parentScope == null) { 
      parentScope = childScope.$parent; 
     } 
     var parentGet = $parse(parentScopeName); 
     var compare = parentGet.literal ? angular.equals : function(a,b) { return a === b; }; 
     var lastValue; 

     var parentSet = parentGet.assign || function() { 
      // reset the change, or we will throw this exception on every $digest 
      lastValue = childScope[scopeName] = parentGet(parentScope); 
      throw "didnt understand this exception"; 
     }; 
     lastValue = childScope[scopeName] = parentGet(parentScope); 
     return childScope.$watch(function parentValueWatch() { 
      var parentValue = parentGet(parentScope); 
      if (!compare(parentValue, childScope[scopeName])) { 
       // we are out of sync and need to copy 
       if (!compare(parentValue, lastValue)) { 
        // parent changed and it has precedence 
        childScope[scopeName] = parentValue; 
       } else { 
        // if the parent can be assigned then do so 
        parentSet(parentScope, parentValue = childScope[scopeName]); 
       } 
      } 
      return (lastValue = parentValue); 
     }, null, parentGet.literal); 
    } 

Так что вы можете делать то, что вы хотите с помощью комбинации этого метода и сервиса $ разбора (вы не сможете использовать изолированную сферу «=» или «@», хотя):

var parsed = $parse($attrs.myAttribute); 
if(parsed.constant) { 
    $scope.whereIWantMyConstantInChildScope = parsed(); 
} else { 
    dataBind($attrs.myAttribute, "whereIWantMyConstantInChildScope", $scope); // 4rth param is optional, will fallback to parent scope. 
} 

Это техническое решение.

Однако, я считаю, что наилучшей практикой было бы обрабатывать эти два случая (постоянное vs привязку) с двумя атрибутами differents (поскольку в основном существуют очень разные потребности и они хотят объединить два поведения, они выглядят в значительной степени похожими на ленивость -development), а if/else - в директиве с выделенной областью. Это позволит избежать всего этого бесполезного перегрева кода ...

+0

Я как бы согласен с последним утверждением, хотя это не связано с лени, и это связано с желанием предоставить пользователям моей каркас гибкость в работе без двух версий каждого атрибута. например директиву карты с атрибутами draggable = "true", latitude = "51.3489" longitude = "0.1246" также потребуются следующие атрибуты: draggable-model = "myScope.draggable" latitude-model = "myScope.latitude" и т. д. Это не так 't кажется очень СУХОЙ, когда у вас много атрибутов, настройка двойных привязок, двойные часы и т. д.Это кажется беспорядочным, но тогда это новое «гибридное» переплетение кажется взломанным. – jonhobbs

+0

Не используйте двойные часы, если они автоматизированы с использованием базовой логики (пример my-attr -> watch, my-attr-static -> constant) и обрабатываются при связывании (это не более чем то, что угловато в изолированной директивной ссылке, и это легко факторизуйте в утилиту) Но это означает снижение всех применений изолированных областей (но это не проблема. ИМХО, отказ от использования отдельных областей применения - это первый необходимый шаг, который не зависит от того, насколько угловые действительно работают и как вы можете оптимизировать материал ...) –

Смежные вопросы