在 emberjs 中重新渲染视图

Posted

技术标签:

【中文标题】在 emberjs 中重新渲染视图【英文标题】:Rerender view in emberjs 【发布时间】:2012-08-23 04:25:58 【问题描述】:

我在 View 中有一个与 Controller 绑定的数组对象。当我更改控制器中的数组时,视图中的数组会正确更改。但我的视图模板似乎已损坏:http://jsfiddle.net/secretlm/2C4c4/84/

当我尝试在视图中使用重新渲染方法时。我的模板没有损坏。这个小提琴效果很好:http://jsfiddle.net/secretlm/2C4c4/85/

html

    <script type="text/x-handlebars" data-template-name="test">
        <button action "changeContent" target="App.latController"> Change</button>
    #each element in view.content
 <!-- if openTag is true, <ol> tag is created -->       
       #if element.openTag
          <ol>                                    
        /if
             <li>element.teo.item.Name</li>
 <!-- if closeTag is true, </ol> tag is created -->
        #if element.closeTag
          </ol>                   
        /if
    /each
   </script>​

javascript

App = Ember.Application.create();

App.LatView = Ember.View.extend(
    templateName: "test",
    contentBinding: "App.latController.contentWithIndices",
    onRerender: function() 
        this.rerender();
        console.log(this.get('content'));
    .observes('content')

);

App.latController = Ember.Object.create(
    changeContent: function() 
        this.set('model', []);
        var model = this.get('model');

        var obj1 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test1",
                "Name": "The name1"
            
        ;
        var obj2 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test2",
                "Name": "The name2"
            
        
        var obj3 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test3",
                "Name": "The name3"
            
        
        var obj4 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test4",
                "Name": "The name4"
            
        
        var obj5 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test5",
                "Name": "The name5"
            
        
        model.pushObject(obj1);
        model.pushObject(obj2);
        model.pushObject(obj3);
        model.pushObject(obj4);
        model.pushObject(obj5);

    ,



    model: [
        
           item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test1",
            "Name": "The name1"
          
       
        ,
    
        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test2",
            "Name": "The name2"
        
    
        ,
    
        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test3",
            "Name": "The name3"
        
    ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test4",
            "Name": "The name4"
        
    ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test5",
            "Name": "The name5"
        
     ],

            contentWithIndices: function() 
                var length = this.get('model').length;
                return this.get('model').map(function(i, idx) 
                    return 
                        teo: i,
                        openTag: (idx % 4 == 0),
                        closeTag: ((idx % 4 == 3) || (idx == length - 1))
                    ;
                );
            .property('model.@each')

        );

        var view = App.LatView.create();
        view.append();

我们什么时候应该手动使用重新渲染方法?有没有办法在不重新渲染我的视图的情况下做到这一点?欢迎任何想法,提前谢谢。

【问题讨论】:

【参考方案1】:

我已尝试使用另一种策略http://jsfiddle.net/davidsevcik/FjB3E/ 重写您的示例

我使用 Array.slice 函数创建四个项目的组,而不是计算索引。也让代码更清晰。

<script type="text/x-handlebars" data-template-name="test">
<button action "changeContent" target="App.latController"> Change</button>
#each elementGroup in view.content
    <ol>    
        #each element in elementGroup                
             <li>element.item.Name</li>
        /each
    </ol>                   
/each
</script>​

Javascript:

App = Ember.Application.create();

App.LatView = Ember.View.extend(
    templateName: "test",
    contentBinding: "App.latController.contentSlicedBy4"
);

App.latController = Ember.Object.create(
    changeContent: function() 
        this.set('model', []);
        var model = this.get('model');

        var obj1 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test1",
                "Name": "The name1"
            
        ;
        var obj2 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test2",
                "Name": "The name2"
            
        
        var obj3 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test3",
                "Name": "The name3"
            
        
        var obj4 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test4",
                "Name": "The name4"
            
        
        var obj5 = 
            item: 
                "DisplayOrder": 1,
                "Public": true,
                "Description": "The test5",
                "Name": "The name5"
            
        
        model.pushObject(obj1);
        model.pushObject(obj2);
        model.pushObject(obj3);
        model.pushObject(obj4);
        model.pushObject(obj5);

    ,



    model: [
        
        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test1",
            "Name": "The name1"
        
        ,
    
        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test2",
            "Name": "The name2"
        
        ,
    
        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test3",
            "Name": "The name3"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test4",
            "Name": "The name4"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test5",
            "Name": "The name5"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test6",
            "Name": "The name6"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test7",
            "Name": "The name7"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test8",
            "Name": "The name8"
        ,
    

        item: 
            "DisplayOrder": 1,
            "Public": true,
            "Description": "The test9",
            "Name": "The name9"
        ],

    contentSlicedBy4: function() 
        var result = [],
            begin = 0,
            model = this.get('model'),
            slice = model.slice(begin, begin + 4);

        while (!Em.empty(slice)) 
            result.push(slice);
            begin += 4;
            slice = model.slice(begin, begin + 4);
        
        return result;
    .property('model.@each', 'model')

);

var view = App.LatView.create();
view.append();​

【讨论】:

感谢您的想法。但是当不使用重新渲染方法时,我的模板仍然损坏。你明白我的问题吗? 好的,我不知道为什么您的特定模板不起作用。但是在使用 ember 几个月后,我发现尝试另一种产生相同结果(通常甚至更好)的方法比通常更快,然后被不工作的解决方案卡住。 哦,我完全同意你的看法。你的想法很有用,你应该更新你的小提琴,因为它仍然使用旧模板。但是,我只能赞成您的回答。非常感谢!

以上是关于在 emberjs 中重新渲染视图的主要内容,如果未能解决你的问题,请参考以下文章

渲染多个 EmberJS 视图时断言失败

EmberJS 从控制器加载视图而不是路由

EmberJS View - 检测是不是所有子视图都已呈现

Emberjs:从子视图中解析表单数据

我可以在 emberjs 中给视图显示动画吗

Emberjs:调用全局操作时重新加载当前状态