今天,在查看ngOptions.js源代码时遇到了这个问题:
getWatchables: $parse(valuesFn, function(values) {
// Create a collection of things that we would like to watch (watchedArray)
// so that they can all be watched using a single $watchCollection
// that only runs the handler once if anything changes
var watchedArray = [];
values = values || [];
Object.keys(values).forEach(function getWatchable(key) {
var locals = getLocals(values[key], key);
var label = displayFn(scope, locals);
var selectValue = getTrackByValue(values[key], locals);
watchedArray.push(selectValue);
watchedArray.push(label);
});
return watchedArray;
}),
但是$ parse的官方文档没有指定任何第二个参数。
它有什么作用 ?
资料来源
v1.3.4:
function addInterceptor(parsedExpression, interceptorFn) {
if (!interceptorFn) return parsedExpression;
var watchDelegate = parsedExpression.$$watchDelegate;
var regularWatch =
watchDelegate !== oneTimeLiteralWatchDelegate &&
watchDelegate !== oneTimeWatchDelegate;
var fn = regularWatch ? function regularInterceptedExpression(scope, locals) {
var value = parsedExpression(scope, locals);
return interceptorFn(value, scope, locals);
} : function oneTimeInterceptedExpression(scope, locals) {
var value = parsedExpression(scope, locals);
var result = interceptorFn(value, scope, locals);
// we only return the interceptor's result if the
// initial value is defined (for bind-once)
return isDefined(value) ? result : value;
};
// Propagate $$watchDelegates other then inputsWatchDelegate
if (parsedExpression.$$watchDelegate &&
parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
fn.$$watchDelegate = parsedExpression.$$watchDelegate;
} else if (!interceptorFn.$stateful) {
// If there is an interceptor, but no watchDelegate then treat the interceptor like
// we treat filters - it is assumed to be a pure function unless flagged with $stateful
fn.$$watchDelegate = inputsWatchDelegate;
fn.inputs = [parsedExpression];
}
return fn;
}
根据上面的示例和angularjs的来源,第二个参数允许您将类似变换的逻辑应用于解析结果。
看https://github.com/angular/angular.js/blob/master/src/ng/directive/ngOptions.js#L461:
// We will re-render the option elements if the option values or labels change
scope.$watchCollection(ngOptions.getWatchables, updateOptions);
似乎,它用于为ngOptions源中的手表提供单一方式。它触发名称和/或标签的更改。如果不使用该表,则该表仅可用于更改标签或仅用于更改值,而不能同时用于两者。
角度代码中使用的其他示例
1.观看ng-bind
var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {
return (value || '').toString();
});
在这里,我们基于转换为字符串的$ parse值构造一个手表。似乎可以在$ digest循环中进行更好和更简单的比较。
2.监视指令中“ =”范围的参数
var parentValueWatch = function parentValueWatch(parentValue) {
if (!compare(parentValue, isolateBindingContext[scopeName])) {
// we are out of sync and need to copy
if (!compare(parentValue, lastValue)) {
// parent changed and it has precedence
isolateBindingContext[scopeName] = parentValue;
} else {
// if the parent can be assigned then do so
parentSet(scope, parentValue = isolateBindingContext[scopeName]);
}
}
return lastValue = parentValue;
};
如您所见,我们只是根据脏检查使范围值保持同步。这就是为什么我们需要第二个$ digest循环来触发指令的内部监视的原因。
概括
似乎这是一种从繁琐的事情转变为一件容易的事情的方法,=
在$ digest-cycle中应该可以通过简单的事情来进行比较。我们是否应该触发监视就需要得出结论。
它还可以用作放置手表通用逻辑的方法。它允许编写一次,并在需要$ parsed值的所有情况下使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句