From 5c8d03e33f32c9238dff49db839d151c23cf9c72 Mon Sep 17 00:00:00 2001 From: James deBoer Date: Fri, 30 May 2014 11:23:33 -0700 Subject: [PATCH] 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 #1086 --- lib/core_dom/element_binder.dart | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/core_dom/element_binder.dart b/lib/core_dom/element_binder.dart index 1fd490892..f7f329416 100644 --- a/lib/core_dom/element_binder.dart +++ b/lib/core_dom/element_binder.dart @@ -83,7 +83,8 @@ class ElementBinder { bool get hasDirectivesOrEvents => _usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty; - void _bindTwoWay(tasks, expression, scope, dstPathFn, controller, formatters, dstExpression) { + void _bindTwoWay(tasks, expression, scope, controllerScope, + dstPathFn, controller, formatters, dstExpression) { var taskId = tasks.registerTask(); Expression expressionFn = _parser(expression); @@ -99,14 +100,14 @@ class ElementBinder { } }, formatters: formatters); if (expressionFn.isAssignable) { - scope.watch(dstExpression, (outboundValue, _) { + controllerScope.watch(dstExpression, (outboundValue, _) { if (!viewOutbound) { viewInbound = true; scope.rootScope.runAsync(() => viewInbound = false); expressionFn.assign(scope.context, outboundValue); tasks.completeTask(taskId); } - }, context: controller, formatters: formatters); + }, formatters: formatters); } } @@ -127,6 +128,7 @@ class ElementBinder { void _createAttrMappings(directive, scope, List mappings, nodeAttrs, formatters, tasks) { + Scope controllerScope; // Only created if there is a two-way binding in the element. mappings.forEach((MappingParts p) { var attrName = p.attrName; var dstExpression = p.dstExpression; @@ -141,7 +143,10 @@ class ElementBinder { var bindAttr = bindAttrs["bind-${p.attrName}"]; if (bindAttr != null) { if (p.mode == '<=>') { - _bindTwoWay(tasks, bindAttr, scope, dstPathFn, + if (controllerScope == null) { + controllerScope = scope.createChild(directive); + } + _bindTwoWay(tasks, bindAttr, scope, controllerScope, dstPathFn, directive, formatters, dstExpression); } else if(p.mode == '&') { _bindCallback(dstPathFn, directive, bindAttr, scope); @@ -162,8 +167,10 @@ class ElementBinder { case '<=>': // two-way if (nodeAttrs[attrName] == null) return; - - _bindTwoWay(tasks, nodeAttrs[attrName], scope, dstPathFn, + if (controllerScope == null) { + controllerScope = scope.createChild(directive); + } + _bindTwoWay(tasks, nodeAttrs[attrName], scope, controllerScope, dstPathFn, directive, formatters, dstExpression); break;