Skip to content

Commit 81618ec

Browse files
committed
feat(ngSrcBoolean)
1 parent 27c6bc0 commit 81618ec

File tree

1 file changed

+51
-27
lines changed

1 file changed

+51
-27
lines changed

lib/directive/ng_src_boolean.dart

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ part of angular.directive;
33
/**
44
* Allows adding and removing the boolean attributes from the element.
55
*
6-
* Using `<button disabled="{{false}}">` does not work since it would result
6+
* Using `<button disabled="false">` does not work since it would result
77
* in `<button disabled="false">` rather than `<button>`.
8-
* Browsers change behavior based on presence/absence of attribute rather the
8+
* Browsers change behavior based on presence/absence of the attribute rather
99
* its value.
1010
*
1111
* For this reason we provide alternate `ng-`attribute directives to
12-
* add/remove boolean attributes such as `<button ng-disabled="{{false}}">`
12+
* add/remove boolean attributes such as `<button ng-disabled="false">`
1313
* which will result in proper removal of the attribute.
1414
*
1515
* The full list of supported attributes are:
@@ -30,18 +30,25 @@ part of angular.directive;
3030
@NgDirective(selector: '[ng-required]', map: const {'ng-required': '=>required'})
3131
@NgDirective(selector: '[ng-selected]', map: const {'ng-selected': '=>selected'})
3232
class NgBooleanAttributeDirective {
33-
final NodeAttrs attrs;
34-
NgBooleanAttributeDirective(this.attrs);
33+
final NgElement _ngElement;
3534

36-
_setBooleanAttribute(name, value) => attrs[name] = (toBool(value) ? '' : null);
35+
NgBooleanAttributeDirective(this._ngElement);
3736

38-
set checked(value) => _setBooleanAttribute('checked', value);
39-
set disabled(value) => _setBooleanAttribute('disabled', value);
40-
set multiple(value) => _setBooleanAttribute('multiple', value);
41-
set open(value) => _setBooleanAttribute('open', value);
42-
set readonly(value) => _setBooleanAttribute('readonly', value);
43-
set required(value) => _setBooleanAttribute('required', value);
44-
set selected(value) => _setBooleanAttribute('selected', value);
37+
void set checked(value) => _toggleAttribute('checked', value);
38+
void set disabled(value) => _toggleAttribute('disabled', value);
39+
void set multiple(value) => _toggleAttribute('multiple', value);
40+
void set open(value) => _toggleAttribute('open', value);
41+
void set readonly(value) => _toggleAttribute('readonly', value);
42+
void set required(value) => _toggleAttribute('required', value);
43+
void set selected(value) => _toggleAttribute('selected', value);
44+
45+
void _toggleAttribute(attrName, [value]) {
46+
if (toBool(value)) {
47+
_ngElement.setAttribute(attrName);
48+
} else {
49+
_ngElement.removeAttribute(attrName);
50+
}
51+
}
4552
}
4653

4754
/**
@@ -61,16 +68,17 @@ class NgBooleanAttributeDirective {
6168
* - [ng-src]
6269
* - [ng-srcset]
6370
*/
71+
// todo(vicb) handle in mustache - but might be no interp
6472
@NgDirective(selector: '[ng-href]', map: const {'ng-href': '@href'})
6573
@NgDirective(selector: '[ng-src]', map: const {'ng-src': '@src'})
6674
@NgDirective(selector: '[ng-srcset]', map: const {'ng-srcset': '@srcset'})
6775
class NgSourceDirective {
68-
final NodeAttrs attrs;
69-
NgSourceDirective(this.attrs);
76+
final NgElement _ngElement;
77+
NgSourceDirective(this._ngElement);
7078

71-
set href(value) => attrs['href'] = value;
72-
set src(value) => attrs['src'] = value;
73-
set srcset(value) => attrs['srcset'] = value;
79+
void set href(value) => _ngElement.setAttribute('href', value);
80+
void set src(value) => _ngElement.setAttribute('src', value);
81+
void set srcset(value) => _ngElement.setAttribute('srcset', value);
7482

7583
}
7684

@@ -84,23 +92,39 @@ class NgSourceDirective {
8492
*
8593
* @example
8694
* <svg>
87-
* <circle ng-attr-cx="{{cx}}"></circle>
95+
* <circle ng-attr-cx="cx"></circle>
8896
* </svg>
8997
*/
98+
// todo(vicb) handle in mustache - but might be no interp
9099
@NgDirective(selector: '[ng-attr-*]')
91100
class NgAttributeDirective implements NgAttachAware {
92-
final NodeAttrs _attrs;
101+
static const NG_ATTR_PREFIX = 'ng-attr-';
102+
final dom.Element _element;
103+
final NgElement _ngElement;
104+
final Scope _scope;
105+
final Interpolate _interpolate;
106+
final FilterMap _filters;
93107

94-
NgAttributeDirective(this._attrs);
108+
NgAttributeDirective(this._element, this._ngElement, this._scope,
109+
this._interpolate, this._filters);
95110

96111
void attach() {
97-
String ngAttrPrefix = 'ng-attr-';
98-
_attrs.forEach((key, value) {
99-
if (key.startsWith(ngAttrPrefix)) {
100-
var newKey = key.substring(ngAttrPrefix.length);
101-
_attrs[newKey] = value;
102-
_attrs.observe(key, (newValue) => _attrs[newKey] = newValue );
112+
_element.attributes.forEach((String rawName, String value) {
113+
if (rawName.startsWith(NG_ATTR_PREFIX)) {
114+
var attrName = rawName.substring(NG_ATTR_PREFIX.length);
115+
var expression = _interpolate(value);
116+
_scope.watch(expression, (v, _) => _updateAttribute(attrName, v),
117+
canChangeModel: false, filters: _filters);
118+
_updateAttribute(attrName, '');
103119
}
104120
});
105121
}
122+
123+
void _updateAttribute(attrName, value) {
124+
if (value == null) {
125+
_ngElement.removeAttribute(attrName);
126+
} else {
127+
_ngElement.setAttribute(attrName, value);
128+
}
129+
}
106130
}

0 commit comments

Comments
 (0)