Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit ca003b2

Browse files
committed
feat(hg-model): basic mg-model support
1 parent 06dd166 commit ca003b2

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

demo/web/index.html

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
</head>
66
<body>
77
<div ng-app>
8+
<h1>ng-model</h1>
9+
<input type="text" ng-model="yourName">
10+
<input type="text" ng-model="yourName">
11+
Hello {{yourName}}!
812
<h1>A Demo of the Bind Directive</h1>
913
<div>
1014
<div ng-bind="greeting"></div>

lib/angular.dart

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ part 'directives/ng_cloak.dart';
2020
part 'directives/ng_controller.dart';
2121
part 'directives/ng_hide.dart';
2222
part 'directives/ng_if.dart';
23+
part 'directives/ng_model.dart';
2324
part 'directives/ng_mustache.dart';
2425
part 'directives/ng_repeat.dart';
2526
part 'directives/ng_show.dart';
@@ -139,6 +140,9 @@ class AngularModule extends Module {
139140
directive(NgIfAttrDirective);
140141
directive(NgRepeatAttrDirective);
141142
directive(NgShowAttrDirective);
143+
144+
directive(InputDirective);
145+
directive(NgModel);
142146
}
143147

144148
directive(Type directive) {

lib/directives/ng_model.dart

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
part of angular;
2+
3+
/**
4+
* Ng-model directive is responsible for reading/writing to the model.
5+
* The directive itself is headless. (It does not know how to render or what
6+
* events to listen for.) It is meant to be used with other directives which
7+
* provide the rendering and listening capabilities. The directive itself
8+
* knows how to convert the view-value into model-value and vice versa by
9+
* allowing others to register converters (To be implemented). It also
10+
* knwos how to (in)validate the model and the form in which it is declared
11+
* (to be implemented)
12+
*/
13+
class NgModel {
14+
static String $selector = '[ng-model]';
15+
16+
Scope scope;
17+
ParsedFn getter;
18+
ParsedAssignFn setter;
19+
20+
Function render = (value) => null;
21+
22+
NgModel(NodeAttrs attrs, Parser parser, Scope this.scope) {
23+
getter = parser(attrs[this]);
24+
setter = getter.assign;
25+
26+
scope.$watch(getter, (value) => render(value) );
27+
}
28+
29+
// TODO(misko): right now viewValue and modelValue are the same,
30+
// but this needs to be changed to support converters and form validation
31+
get viewValue => modelValue;
32+
set viewValue(value) => modelValue = value;
33+
34+
get modelValue => getter(scope);
35+
set modelValue(value) => setter(scope, value);
36+
}
37+
38+
/**
39+
* The UI portion of the ng-model directive. This directive registers the UI
40+
* events and provides a rendering function for the ng-model directive.
41+
*/
42+
class InputDirective {
43+
static String $selector = 'input[ng-model]';
44+
45+
dom.InputElement inputElement;
46+
NgModel ngModel;
47+
Scope scope;
48+
49+
InputDirective(dom.Element this.inputElement, NgModel this.ngModel, Scope this.scope) {
50+
ngModel.render = (value) => inputElement.value = value == null ? '' : value;
51+
52+
inputElement.onChange.listen(_relaxFnArgs(processValue));
53+
inputElement.onKeyDown.listen((e) => new async.Timer(Duration.ZERO, processValue));
54+
}
55+
56+
processValue() {
57+
var value = inputElement.value;
58+
if (value != ngModel.viewValue) {
59+
scope.$apply(() => ngModel.viewValue = value);
60+
}
61+
}
62+
}

test/directives/ng_model_spec.dart

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import "../_specs.dart";
2+
import "../_test_bed.dart";
3+
4+
main() =>
5+
describe('ng-model', () {
6+
TestBed _;
7+
8+
beforeEach(beforeEachTestBed((tb) => _ = tb));
9+
10+
describe('type="text"', () {
11+
it('should update input value from model', inject(() {
12+
_.compile('<input ng-model="model">');
13+
_.rootScope.$digest();
14+
15+
expect(_.rootElement.prop('value')).toEqual('');
16+
17+
_.rootScope.$apply('model = "misko"');
18+
expect(_.rootElement.prop('value')).toEqual('misko');
19+
}));
20+
21+
it('should update model from the input value', inject(() {
22+
_.compile('<input ng-model="model" probe="p">');
23+
Probe probe = _.rootScope.p;
24+
var ngModel = probe.directive(NgModel);
25+
var input = probe.directive(InputDirective);
26+
27+
probe.element.value = 'abc';
28+
input.processValue();
29+
expect(_.rootScope.model).toEqual('abc');
30+
}));
31+
});
32+
});

0 commit comments

Comments
 (0)