canjs attach Control for element in Observe.List after render

471 views Asked by At

Generally the problem is that my click action in Control doesn't work.

In codes below you can see situation when i generate list with items using Observe.List, so it's updated when new element occurs on the list automatically (view below) and it's generated in first Control in init func.

Also in first control When new elements are put on the list I attach Control to it '{files} add' method for new generated element.

The problem is that in second control click event won't work. I think that because I try to do that before automatic regenerate Observe.List was finish. The proof is that jquery doesn't element yet.

Is it possible that I attach Contol ('{files} add') before it's render by automatic regenerate Observe.List? How Should I set Control on new element in proper way? Can I do that somehow in view?

define(['canjs/can',
'text!platform/presenter/views/file_list.ejs',
'platform/presenter/file',
'platform/presenter/show',],
function(can,EjsFileList,ControlFile,ControlShow){
    var file_list = can.Control({

    },{
        'init': function(){
            "use strict";
             can.view.ejs('EjsFileList',EjsFileList);
             can.view( "EjsFileList", {
                files : this.options.files
            }, $.proxy( function( fragment ) {
                this.element.html( fragment );

            },this));

        },


        '{files} add': function(list,event  ,added){


            list.forEach($.proxy(function(el){
            console.log($('#file-' + el.id));
            // HERE IS PROBLEM
            //[context: document, selector: "#file-80", jquery: "1.9.1", constructor:           function, init: //function…]
            //context: document 
            //selector: "#file-80"
            //__proto__: Object[0]

                new ControlFile('#file-' + el.id  ,{
                    'file': el,
                    'files': list
                });
            },this));
        },
        '{files} remove': function(a,b,removed){
            removed.forEach(function(element){
                $('#file-' + element.id).remove();
            });
        }



    });
    return file_list;
});

the view for list:

<%  files.each(function(file){  %>
<li id="file-<%= file.id %>" <%= (el) -> can.data(el, 'file', file)  %> class="<%= file.attr('public')? '' : '     private ' %>">
    <img class="loading" />
</li>
 <% }); %>

Control for list element. Here is problem!

  define(['canjs/can',
'platform/model/file',
'platform/presenter/show',
'text!platform/presenter/views/file.ejs',
 ],
function(can, modelFile,ControlShow,EjsFile){


    var list = can.Control({
        defaults: {
            loaderClass: 'loading',
            model: modelFile
        }
    },{
        'init': function(){
            "use strict";
            console.log(this.element);
            //[context: document, selector: "#file-73", jquery: "1.9.1", constructor: function, init: function…]


        },

        'img click': function(){
            console.log('should work but never gets here');

        }


    });

    return list;

});
1

There are 1 answers

0
Dawid Dereszewski On BEST ANSWER

I found the solution.

If you using dynamic list in canjs and want to attach Control on each element you should create the view like below:

<% files.each(function(file){  %>
    <li id="file-<%= file.id %>" <%= (el) -> can.data(el, 'file', file)  %>
    <%= function(element){ new ControlFile(element, {file: file}); } %>>
    <img class="loading" />
</li>
<% }); %>

As you can see I set up Control on the list, but I need to pass to view every variable that Control using.