开发者

How to load multiple items into a container and initialize them?

I'm trying to create a simple web system that loads an arbitrary number of items (each which defines its own HTML rendering and dynamic behavior) in a container. The container will determine which items to load, load their HTML from the server, then initialize them with parameters. Here's a simplified example:

<!-- container.xhtml -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"/>
    <script>
        var params = {};
        $(document).ready(function() {
            params = {'text': 'Text A'};
            resp = $.get('item.xhtml', function(data) {
                $('.container').append(data);
                // want to initialize the new node
                data.init(params);
            });
            params = {'text': 'Text B'};
            resp = $.get('item.xhtml', function(data) {
                $('.container').append(data);
                // want to initialize the new node
                data.init(params);
            });
        });
    </script>
    <div class="container">
    </div>
</body>
</html>

And an example of an item:

<?xml version="1.0" encoding="UTF-8"?>
<!-- item.xhtml -->
<div class="item" xmlns="http://www.w3.org/1999/xhtml">
    <script>
        <!-- want this function to be called for each "item" node created -->
        function initialize(item, params) {
            item.find('.dynamic').text(params['text']);
        }
    </script>
    <div class="some_class">
        Some Content
    </div>
    <div class="dynamic">
        Replace me
    </div>
</div>

The challenge I face is I'm unable to assign the on_load function with its item. I can't give div[@class='item'] an ID because it may be loaded multiple times.

I want to maintain a simple container that needs only load 开发者_开发问答a file and call some prescribed function to initialize the item. If it's absolutely necessary to modify the container to enable this model, it's important to minimize the interface between the container and item.

Is it possible to change only the code for item.xhtml such that when it is loaded by container.xhtml, the calls to data.init() will call the initialize() function with the appropriate item node and params? If not, how can one achieve this model by other means? Is there a better approach for this problem?


Simple example to point in a direction:

What about attaching your code to the element, using a custom event, and then call that event when its loaded. Something like...

    <script>
          $('.item').bind("init",function(params){
            this.text(params['text']);
         });
    </script>

and calls it

EDIT : Correct my stupid calling snytax

$('.item:last').trigger('init',[{'text': 'Text B']);


After several hours of flailing, I managed to get pretty close.

Container:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"/>
    <script>
        var params = {};
        $(document).ready(function() {
            param_list = [
                {'text': 'Text A'},
                {'text': 'Text B'},
                {'text': 'Text C'}];
            for(param_index in param_list) {
                var params = param_list[param_index];
                init_func = function(params) {
                    return function(data) {
                        var node = $(data.documentElement)
                        $('.container').append(node);
                        // want to initialize the new node
                        node.trigger("initialize", [params]);
                    };
                }
                resp = $.get('item.xhtml', init_func(param_list[param_index]));
            }
        });
    </script>
    <div class="container">
    </div>
</body>
</html>

Item:

<?xml version="1.0" encoding="UTF-8"?>
<div id="item" xmlns="http://www.w3.org/1999/xhtml">
    <script>
        <!-- want this function to be called for each "item" node created -->
        $('#item').bind("initialize", function(event, params) {
            $(this).find('.dynamic').text(params['text']);
        }).removeAttr('id');
    </script>
    <div class="dynamic">
        Other content
    </div>
</div>

Note there are two limitations:

  1. The item designer must assign an ID to the node and remove it during construction. This appears to be the only way for his own javascript to bind to his own node. The ID has to be removed so it doesn't conflict with subsequently-added items.
  2. This fails in Chrome (with WRONG_DOCUMENT_ERR) because Chrome honors the W3C standard that says a DOM node can't be added from one document to another. It works in Firefox, however. Next step is to figure out how to load a node dynamically without the WRONG_DOCUMENT_ERR.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜