重新渲染视图时如何控制文本字段焦点?

时间:2014-02-21 00:15:36

标签: javascript ember.js

我正在使用Ember.js开发一个表编辑器。我创建了一个名为FocusedTextField的视图,在渲染文本字段时对其进行聚焦。我想实现一个Tab键功能,以便命中选项卡将下一个单元格集中在一行。当前代码将当前选定的单元格更改为不可编辑,并将下一个单元格更改为文本字段,但不会关注下一个字段的值。似乎代码不起作用是时间的影响。什么是解决这个问题的更好方法?

这是我的JSBin:http://emberjs.jsbin.com/tey/12/edit

jQuery 1.10.2 把手1.2.1 Ember 1.1.2

HTML:

<script type="text/x-handlebars" data-template-name="row">
    <tr>
        {{#collection cellCollection}}
            {{view view.content.view}}
        {{/collection}}
    </tr>
</script>

<script type="text/x-handlebars" data-template-name="cell">
    <td {{action "click"}}>
        {{#if editMode}}
            {{view textField valueBinding=value}}
        {{else}}
            {{value}}
        {{/if}}
    </td>
</script>

<script type="text/x-handlebars" data-template-name="table">
    <table>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Points</th>
        </tr>

        {{#collection rowCollection}}
            {{view view.content.view}}
        {{/collection}}
    </table>
</script>

<div id="main"></div>

JavaScript的:

App = Ember.Application.create();

var TemplatedViewController = Ember.Object.extend({
    templateFunction: null,
    viewArgs: null,
    viewBaseClass: Ember.View,
    view: function () {
        var controller = this;
        var viewArgs = this.get('viewArgs') || {};
        var args = {
            template: controller.get('templateFunction'),
            controller: controller
        };
        args = $.extend(viewArgs, args);
        return this.get('viewBaseClass').extend(args);
    }.property('templateFunction', 'viewArgs'),
    appendView: function (selector) {
        this.get('view').create().appendTo(selector);
    },
    appendViewToBody: function () {
        this.get('view').create().append();
    },
    appendPropertyViewToBody: function (property) {
        this.get(property).create().append();
    }
});

var FocusedTextField = Ember.TextField.extend({
    focusTheTextField: function() {
        this.$().focus();
    }.on('didInsertElement')
});

var Cell = TemplatedViewController.extend({
    row: null,
    editMode: false,
    value: null,
    textField: function () {
        var cell = this;
        return FocusedTextField.extend({
            keyDown: function (event) {
                // Hitting the enter key disables edit mode
                if (event.keyCode === 13) {
                    cell.set('editMode', false);
                // Hitting the tab key selects the next cell
                } else if (event.keyCode === 9) {
                    cell.set('editMode', false);
                    var nextCell = cell.getNextCell();
                    nextCell.set('editMode', true);
                }
            }
        });
    }.property(),
    flipEditMode: function () {
        if (this.get('editMode')) {
            this.set('editMode', false);
        } else {
            this.set('editMode', true);
        }
    },
    click: function () {
        console.log('cell clicked, value: '+this.get('value'));
        this.flipEditMode();
    },
    getNextCell: function () {
        return this.get('row').getNextCell(this);
    },
    view: function () {
        var controller = this;
        return this.get('viewBaseClass').extend({
            controller: controller,
            templateName: 'cell'
        });
    }.property()
});

var Row = TemplatedViewController.extend({
    headers: ['firstName', 'lastName', 'points'],
    firstName: null,
    lastName: null,
    points: null,
    cells: null,
    cellCollection: function () {
        return Ember.CollectionView.extend({
            content: this.get('cells')
        });
    }.property('cells'),
    init: function () {
        this._super();
        var row = this;
        var cells = [];
        this.get('headers').forEach(function (item, index, enumerable) {
            var header = item;
            var value = row.get(header);
            var cell = Cell.create({
                row: row,
                value: value
            });
            cells.pushObject(cell);
        });
        this.set('cells', cells);
    },
    getNextCell: function (cell) {
        if (this.get('cells').contains(cell)) {
            var lastIndex = this.get('cells').length - 1;
            var cellIndex = this.get('cells').indexOf(cell);
            if (cellIndex < lastIndex) {
                var nextIndex = cellIndex + 1;
                return this.get('cells')[nextIndex];
            }
        }
    },
    view: function () {
        var controller = this;
        return this.get('viewBaseClass').extend({
            controller: controller,
            templateName: 'row'
        });
    }.property()
});

var rows = [];

var DATA = [
    {first_name: 'Jill', last_name: 'Smith', points: 50},
    {first_name: 'Eve', last_name: 'Jackson', points: 94},
    {first_name: 'John', last_name: 'Doe', points: 80},
    {first_name: 'Adam', last_name: 'Johnson', points: 67}
];

DATA.forEach(function (item, index, enumerable) {
    var row = Row.create({
        firstName: item.first_name,
        lastName: item.last_name,
        points: item.points
    });
    rows.pushObject(row);
});

var Table = TemplatedViewController.extend({
    view: function () {
        var controller = this;
        return this.get('viewBaseClass').extend({
            controller: controller,
            templateName: 'table'
        });
    }.property(),
    rows: null,
    rowCollection: function () {
        return Ember.CollectionView.extend({
            content: this.get('rows')
        });
    }.property('rows')
});

var table = Table.create({rows: rows});

$(function () {
    table.appendView('#main');
});

1 个答案:

答案 0 :(得分:3)

focus()中的Ember.run.next电话转接到var FocusedTextField = Ember.TextField.extend({ focusTheTextField: function() { var self = this; Ember.run.next( function() { self.$().focus(); }); }.on('didInsertElement') }); ,如下所示:

Ember.run.next

有关{{1}}的说明,请参阅:http://emberjs.com/api/classes/Ember.run.html#method_next Ember运行循环的良好描述:What is Ember RunLoop and how does it work?