(scope, attrs, destination, bindings,
directive, newScope)
| 8657 | // Set up $watches for isolate scope and controller bindings. This process |
| 8658 | // only occurs for isolate scopes and new scopes with controllerAs. |
| 8659 | function initializeDirectiveBindings(scope, attrs, destination, bindings, |
| 8660 | directive, newScope) { |
| 8661 | var onNewScopeDestroyed; |
| 8662 | forEach(bindings, function(definition, scopeName) { |
| 8663 | var attrName = definition.attrName, |
| 8664 | optional = definition.optional, |
| 8665 | mode = definition.mode, // @, =, or & |
| 8666 | lastValue, |
| 8667 | parentGet, parentSet, compare; |
| 8668 | |
| 8669 | if (!hasOwnProperty.call(attrs, attrName)) { |
| 8670 | // In the case of user defined a binding with the same name as a method in Object.prototype but didn't set |
| 8671 | // the corresponding attribute. We need to make sure subsequent code won't access to the prototype function |
| 8672 | attrs[attrName] = undefined; |
| 8673 | } |
| 8674 | |
| 8675 | switch (mode) { |
| 8676 | |
| 8677 | case '@': |
| 8678 | if (!attrs[attrName] && !optional) { |
| 8679 | destination[scopeName] = undefined; |
| 8680 | } |
| 8681 | |
| 8682 | attrs.$observe(attrName, function(value) { |
| 8683 | destination[scopeName] = value; |
| 8684 | }); |
| 8685 | attrs.$$observers[attrName].$$scope = scope; |
| 8686 | if (attrs[attrName]) { |
| 8687 | // If the attribute has been provided then we trigger an interpolation to ensure |
| 8688 | // the value is there for use in the link fn |
| 8689 | destination[scopeName] = $interpolate(attrs[attrName])(scope); |
| 8690 | } |
| 8691 | break; |
| 8692 | |
| 8693 | case '=': |
| 8694 | if (optional && !attrs[attrName]) { |
| 8695 | return; |
| 8696 | } |
| 8697 | parentGet = $parse(attrs[attrName]); |
| 8698 | |
| 8699 | if (parentGet.literal) { |
| 8700 | compare = equals; |
| 8701 | } else { |
| 8702 | compare = function(a, b) { return a === b || (a !== a && b !== b); }; |
| 8703 | } |
| 8704 | parentSet = parentGet.assign || function() { |
| 8705 | // reset the change, or we will throw this exception on every $digest |
| 8706 | lastValue = destination[scopeName] = parentGet(scope); |
| 8707 | throw $compileMinErr('nonassign', |
| 8708 | "Expression '{0}' used with directive '{1}' is non-assignable!", |
| 8709 | attrs[attrName], directive.name); |
| 8710 | }; |
| 8711 | lastValue = destination[scopeName] = parentGet(scope); |
| 8712 | var parentValueWatch = function parentValueWatch(parentValue) { |
| 8713 | if (!compare(parentValue, destination[scopeName])) { |
| 8714 | // we are out of sync and need to copy |
| 8715 | if (!compare(parentValue, lastValue)) { |
| 8716 | // parent changed and it has precedence |
no test coverage detected