Skip to content

Commit 6051340

Browse files
committed
feat(element binder): Use a child scope instead of Scope.watch(context:o)
This is the only place where Scope.watch(context:o) is used and it is in the way of optimizations. For dart-archive#1086
1 parent db72a4f commit 6051340

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

lib/core_dom/element_binder.dart

+13-6
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ class ElementBinder {
8383
bool get hasDirectivesOrEvents =>
8484
_usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty;
8585

86-
void _bindTwoWay(tasks, expression, scope, dstPathFn, controller, formatters, dstExpression) {
86+
void _bindTwoWay(tasks, expression, scope, directiveScope,
87+
dstPathFn, controller, formatters, dstExpression) {
8788
var taskId = tasks.registerTask();
8889
Expression expressionFn = _parser(expression);
8990

@@ -99,14 +100,14 @@ class ElementBinder {
99100
}
100101
}, formatters: formatters);
101102
if (expressionFn.isAssignable) {
102-
scope.watch(dstExpression, (outboundValue, _) {
103+
directiveScope.watch(dstExpression, (outboundValue, _) {
103104
if (!viewOutbound) {
104105
viewInbound = true;
105106
scope.rootScope.runAsync(() => viewInbound = false);
106107
expressionFn.assign(scope.context, outboundValue);
107108
tasks.completeTask(taskId);
108109
}
109-
}, context: controller, formatters: formatters);
110+
}, formatters: formatters);
110111
}
111112
}
112113

@@ -127,6 +128,7 @@ class ElementBinder {
127128

128129
void _createAttrMappings(directive, scope, List<MappingParts> mappings, nodeAttrs, formatters,
129130
tasks) {
131+
Scope directiveScope; // Only created if there is a two-way binding in the element.
130132
mappings.forEach((MappingParts p) {
131133
var attrName = p.attrName;
132134
var dstExpression = p.dstExpression;
@@ -141,7 +143,10 @@ class ElementBinder {
141143
var bindAttr = bindAttrs["bind-${p.attrName}"];
142144
if (bindAttr != null) {
143145
if (p.mode == '<=>') {
144-
_bindTwoWay(tasks, bindAttr, scope, dstPathFn,
146+
if (directiveScope == null) {
147+
directiveScope = scope.createChild(directive);
148+
}
149+
_bindTwoWay(tasks, bindAttr, scope, directiveScope, dstPathFn,
145150
directive, formatters, dstExpression);
146151
} else if(p.mode == '&') {
147152
_bindCallback(dstPathFn, directive, bindAttr, scope);
@@ -162,8 +167,10 @@ class ElementBinder {
162167

163168
case '<=>': // two-way
164169
if (nodeAttrs[attrName] == null) return;
165-
166-
_bindTwoWay(tasks, nodeAttrs[attrName], scope, dstPathFn,
170+
if (directiveScope == null) {
171+
directiveScope = scope.createChild(directive);
172+
}
173+
_bindTwoWay(tasks, nodeAttrs[attrName], scope, directiveScope, dstPathFn,
167174
directive, formatters, dstExpression);
168175
break;
169176

0 commit comments

Comments
 (0)