UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

168 lines 7.85 kB
'use strict';var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc); switch (arguments.length) { case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target); case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0); case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); } }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var core_1 = require('angular2/core'); var lang_1 = require('angular2/src/facade/lang'); /** * The `NgFor` directive instantiates a template once per item from an iterable. The context for * each instantiated template inherits from the outer context with the given loop variable set * to the current item from the iterable. * * # Local Variables * * `NgFor` provides several exported values that can be aliased to local variables: * * * `index` will be set to the current loop iteration for each template context. * * `last` will be set to a boolean value indicating whether the item is the last one in the * iteration. * * `even` will be set to a boolean value indicating whether this item has an even index. * * `odd` will be set to a boolean value indicating whether this item has an odd index. * * # Change Propagation * * When the contents of the iterator changes, `NgFor` makes the corresponding changes to the DOM: * * * When an item is added, a new instance of the template is added to the DOM. * * When an item is removed, its template instance is removed from the DOM. * * When items are reordered, their respective templates are reordered in the DOM. * * Otherwise, the DOM element for that item will remain the same. * * Angular uses object identity to track insertions and deletions within the iterator and reproduce * those changes in the DOM. This has important implications for animations and any stateful * controls * (such as `<input>` elements which accept user input) that are present. Inserted rows can be * animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state such * as user input. * * It is possible for the identities of elements in the iterator to change while the data does not. * This can happen, for example, if the iterator produced from an RPC to the server, and that * RPC is re-run. Even if the data hasn't changed, the second response will produce objects with * different identities, and Angular will tear down the entire DOM and rebuild it (as if all old * elements were deleted and all new elements inserted). This is an expensive operation and should * be avoided if possible. * * # Syntax * * - `<li *ng-for="#item of items; #i = index">...</li>` * - `<li template="ng-for #item of items; #i = index">...</li>` * - `<template ng-for #item [ng-for-of]="items" #i="index"><li>...</li></template>` * * ### Example * * See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed * example. */ var NgFor = (function () { function NgFor(_viewContainer, _templateRef, _iterableDiffers, _cdr) { this._viewContainer = _viewContainer; this._templateRef = _templateRef; this._iterableDiffers = _iterableDiffers; this._cdr = _cdr; } Object.defineProperty(NgFor.prototype, "ngForOf", { set: function (value) { this._ngForOf = value; if (lang_1.isBlank(this._differ) && lang_1.isPresent(value)) { this._differ = this._iterableDiffers.find(value).create(this._cdr); } }, enumerable: true, configurable: true }); Object.defineProperty(NgFor.prototype, "ngForTemplate", { set: function (value) { if (lang_1.isPresent(value)) { this._templateRef = value; } }, enumerable: true, configurable: true }); NgFor.prototype.ngDoCheck = function () { if (lang_1.isPresent(this._differ)) { var changes = this._differ.diff(this._ngForOf); if (lang_1.isPresent(changes)) this._applyChanges(changes); } }; NgFor.prototype._applyChanges = function (changes) { // TODO(rado): check if change detection can produce a change record that is // easier to consume than current. var recordViewTuples = []; changes.forEachRemovedItem(function (removedRecord) { return recordViewTuples.push(new RecordViewTuple(removedRecord, null)); }); changes.forEachMovedItem(function (movedRecord) { return recordViewTuples.push(new RecordViewTuple(movedRecord, null)); }); var insertTuples = this._bulkRemove(recordViewTuples); changes.forEachAddedItem(function (addedRecord) { return insertTuples.push(new RecordViewTuple(addedRecord, null)); }); this._bulkInsert(insertTuples); for (var i = 0; i < insertTuples.length; i++) { this._perViewChange(insertTuples[i].view, insertTuples[i].record); } for (var i = 0, ilen = this._viewContainer.length; i < ilen; i++) { this._viewContainer.get(i).setLocal('last', i === ilen - 1); } }; NgFor.prototype._perViewChange = function (view, record) { view.setLocal('\$implicit', record.item); view.setLocal('index', record.currentIndex); view.setLocal('even', (record.currentIndex % 2 == 0)); view.setLocal('odd', (record.currentIndex % 2 == 1)); }; NgFor.prototype._bulkRemove = function (tuples) { tuples.sort(function (a, b) { return a.record.previousIndex - b.record.previousIndex; }); var movedTuples = []; for (var i = tuples.length - 1; i >= 0; i--) { var tuple = tuples[i]; // separate moved views from removed views. if (lang_1.isPresent(tuple.record.currentIndex)) { tuple.view = this._viewContainer.detach(tuple.record.previousIndex); movedTuples.push(tuple); } else { this._viewContainer.remove(tuple.record.previousIndex); } } return movedTuples; }; NgFor.prototype._bulkInsert = function (tuples) { tuples.sort(function (a, b) { return a.record.currentIndex - b.record.currentIndex; }); for (var i = 0; i < tuples.length; i++) { var tuple = tuples[i]; if (lang_1.isPresent(tuple.view)) { this._viewContainer.insert(tuple.view, tuple.record.currentIndex); } else { tuple.view = this._viewContainer.createEmbeddedView(this._templateRef, tuple.record.currentIndex); } } return tuples; }; NgFor = __decorate([ core_1.Directive({ selector: '[ng-for][ng-for-of]', inputs: ['ngForOf', 'ngForTemplate'] }), __metadata('design:paramtypes', [core_1.ViewContainerRef, core_1.TemplateRef, core_1.IterableDiffers, core_1.ChangeDetectorRef]) ], NgFor); return NgFor; })(); exports.NgFor = NgFor; var RecordViewTuple = (function () { function RecordViewTuple(record, view) { this.record = record; this.view = view; } return RecordViewTuple; })(); //# sourceMappingURL=ng_for.js.map