Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions lib/directive/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* This package is imported for you as part of [angular.dart](#angular/angular),
* and lists all of the basic directives that are part of Angular.
*
*
*/
library angular.directive;

Expand Down Expand Up @@ -69,8 +68,8 @@ class NgDirectiveModule extends Module {
value(ContentEditableDirective, null);
value(NgModel, null);
value(NgValue, new NgValue(null));
value(NgTrueValue, new NgTrueValue(null));
value(NgFalseValue, new NgFalseValue(null));
value(NgTrueValue, new NgTrueValue());
value(NgFalseValue, new NgFalseValue());
value(NgSwitchDirective, null);
value(NgSwitchWhenDirective, null);
value(NgSwitchDefaultDirective, null);
Expand Down
85 changes: 50 additions & 35 deletions lib/directive/ng_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,32 @@ class NgModel extends NgControl implements NgAttachAware {
/**
* Usage:
*
* <input type="checkbox" ng-model="flag">
* <input type="checkbox"
* ng-model="expr"
* [ng-true-value="t_expr"]
* [ng-false-value="f_expr"]
* >
*
* This creates a two way databinding between the boolean expression specified
* in ng-model and the checkbox input element in the DOM.  If the ng-model value
* is falsy (i.e. one of `false`, `null`, and `0`), then the checkbox is
* unchecked. Otherwise, it is checked.  Likewise, when the checkbox is checked,
* the model value is set to true. When unchecked, it is set to false.
* This creates a two way databinding between the `ng-model` expression
* and the checkbox input element state.
*
* If the optional `ng-true-value` is absent then: if the model expression
* evaluates to true or to a nonzero [num], then the checkbox is checked;
* otherwise, it is unchecked.
*
* If `ng-true-value="t_expr"` is present, then: if the model expression
* evaluates to the same value as `t_expr` then the checkbox is checked;
* otherwise, it is unchecked.
*
* When the checkbox is checked, the model is set to the value of `t_expr` if
* present, true otherwise. When unchecked, it is set to the value of
* `f_expr` if present, false otherwise.
*
* Also see [NgTrueValue] and [NgFalseValue].
*/
@NgDirective(selector: 'input[type=checkbox][ng-model]')
class InputCheckboxDirective {
final dom.InputElement inputElement;
final dom.CheckboxInputElement inputElement;
final NgModel ngModel;
final NgTrueValue ngTrueValue;
final NgFalseValue ngFalseValue;
Expand All @@ -285,14 +300,13 @@ class InputCheckboxDirective {
this.scope, this.ngTrueValue, this.ngFalseValue) {
ngModel.render = (value) {
scope.rootScope.domWrite(() {
inputElement.checked = ngTrueValue.isValue(inputElement, value);
inputElement.checked = ngTrueValue.isValue(value);
});
};
inputElement
..onChange.listen((value) {
..onChange.listen((_) {
ngModel.viewValue = inputElement.checked
? ngTrueValue.readValue(inputElement)
: ngFalseValue.readValue(inputElement);
? ngTrueValue.value : ngFalseValue.value;
})
..onBlur.listen((e) {
ngModel.markAsTouched();
Expand Down Expand Up @@ -473,44 +487,45 @@ class NgValue {
}

/**
* `ng-true-value` allows you to select any expression to be set to
* `ng-model` when checkbox is selected on `<input type="checkbox">`.
* Usage:
*
* <input type=checkbox
* ng-model=model
* [ng-true-value=expr]>
*
* The initial value of the expression bound to this directive is assigned to
* the model when the input is checked. Note that the expression can be of any
* type, not just [String]. Also see [InputCheckboxDirective], [NgFalseValue].
*/
@NgDirective(selector: '[ng-true-value]')
@NgDirective(selector: 'input[type=checkbox][ng-model][ng-true-value]')
class NgTrueValue {
final dom.Element element;
@NgOneWay('ng-true-value')
var value;

NgTrueValue(this.element);
var value = true;

readValue(dom.Element element) {
assert(this.element == null || element == this.element);
return this.element == null ? true : value;
}
NgTrueValue([this.element]);

bool isValue(dom.Element element, value) {
assert(this.element == null || element == this.element);
return this.element == null ? toBool(value) : value == this.value;
}
bool isValue(val) => element == null ? toBool(val) : val == value;
}

/**
* `ng-false-value` allows you to select any expression to be set to
* `ng-model` when checkbox is deselected <input type="checkbox">`.
* Usage:
*
* <input type=checkbox
* ng-model=model
* [ng-false-value=expr]>
*
* The initial value of the expression bound to this directive is assigned to
* the model when the input is unchecked. Note that the expression can be of any
* type, not just [String]. Also see [InputCheckboxDirective], [NgTrueValue].
*/
@NgDirective(selector: '[ng-false-value]')
@NgDirective(selector: 'input[type=checkbox][ng-model][ng-false-value]')
class NgFalseValue {
final dom.Element element;
@NgOneWay('ng-false-value')
var value;

NgFalseValue(this.element);
var value = false;

readValue(dom.Element element) {
assert(this.element == null || element == this.element);
return this.element == null ? false : value;
}
NgFalseValue([this.element]);
}

/**
Expand Down
20 changes: 17 additions & 3 deletions test/directive/ng_model_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,6 @@ void main() {
expect(model.dirty).toEqual(true);
});


it('should update input value from model using ng-true-value/false', (Scope scope) {
var element = _.compile('<input type="checkbox" ng-model="model" ng-true-value="1" ng-false-value="0">');

Expand All @@ -654,7 +653,6 @@ void main() {
expect(scope.context['model']).toBe(0);
});


it('should allow non boolean values like null, 0, 1', (Scope scope) {
var element = _.compile('<input type="checkbox" ng-model="model">');

Expand All @@ -674,7 +672,6 @@ void main() {
expect(element.checked).toBe(false);
});


it('should update model from the input value', (Scope scope) {
var element = _.compile('<input type="checkbox" ng-model="model">');

Expand All @@ -687,6 +684,23 @@ void main() {
expect(scope.context['model']).toBe(false);
});

it('should update model from the input using ng-true-value/false', (Scope scope) {
var element = _.compile('<input type="checkbox" ng-model="model" '
'ng-true-value="yes" ng-false-value="no">');
scope.apply(() {
scope.context['yes'] = 'yes sir!';
scope.context['no'] = 'no, sorry';
});

element.checked = true;
_.triggerEvent(element, 'change');
expect(scope.context['model']).toEqual('yes sir!');

element.checked = false;
_.triggerEvent(element, 'change');
expect(scope.context['model']).toEqual('no, sorry');
});

it('should only render the input value upon the next digest', (Scope scope) {
_.compile('<input type="checkbox" ng-model="model" probe="p">');
Probe probe = _.rootScope.context['p'];
Expand Down