attachElementBindingSync

Can anybody explain what is this binding(Web.Bindings) all about and when to use "attachElementBindingSync" method

Thanks



Answer this question

attachElementBindingSync

  • Paul Stovell

    The best way to learn about bindings is to read the SDK and API reference.

    In a nutshell, a binding is a self-contained component that does its own initialization and cleanup and can expose events and methods for others to call. A binding can be as simple or as complex as you like. A simple example would be the binding that gives a button the live.com look-and-feel (blue gradient background). A more complex example would be a binding that acts as a UI control, such as a filmstrip control (seen in a few Microsoft gadgets). Another example would be your gadget's main class -- that itself is a binding that live.com uses to present your gadget.

    As I first mentioned, the SDK is probably the best place to get started with bindings. If you like I can share some examples of bindings I've built for my various gadgets as well.

    Going slightly off-topic: There's no good place to share bindings. Gallery hosts gadgets, but there's no central repository for interesting bindings that people have written and would like to share with others. As well, while live.com does expose a few bindings in the Start.* namespace, there's no documentation on these at all (with good reason -- Start.* is not meant for public consumption can could change at any time). It'd be really great if the live.com or Spaces teams could define a public namespace that contains bindings we can use with no fear of them changing or going away like those in the Start.* namespace.


  • Ram Shriram

    I'm back with code. Let me first apologize because the formatting here sucks. I'll try my best, but there's only so much you can do in the comment box. With that said, onto the code!

    First, here's some code for a simple binding. This defines a simple loading screen you can use within a gadget. I'll comment on the code below.

    registerNamespace("ToddOs.Utils");
    ToddOs.Utils.LoadingPanel =
    function(p_elSource, p_args, p_namespace)
    {
    ToddOs.Utils.LoadingPanel.initializeBase(
    this, arguments);
    var m_this = this;
    // must be a valid CSS value for display that's appropriate for p_elSource. Generally use "block"
    var m_displayStyle = p_args.displayStyle;

    this.Show = function()
    {
    if (m_displayStyle == null)
    {
    p_elSource.style.display =
    "block";
    }
    else
    {
    p_elSource.style.display = m_displayStyle;
    }
    }

    this.Hide = function()
    {
    p_elSource.style.display =
    "none";
    }

    this.initialize = function(p_objScope)
    {
    ToddOs.Utils.LoadingPanel.getBaseMethod(
    this, "initialize", "Web.Bindings.Base").call(this, p_objScope);
    p_elSource.appendChild(document.createTextNode(
    "Loading ..."));
    };

    this.dispose = function(p_blnUnload)
    {
    ToddOs.Utils.LoadingPanel.getBaseMethod(
    this, "dispose", "Web.Bindings.Base").call(this, p_blnUnload);
    };
    }

    ToddOs.Utils.LoadingPanel.registerClass("ToddOs.Utils.LoadingPanel", "Web.Bindings.Base");

    As I mentioned, very simple. This should already look familiar to you if you've written a gadget, because your main gadget class is also a binding. The class itself gets the usual p_elSource, p_args, and p_namespace parameters, and there are the familiar this.initialize() and this.dispose() methods as well. The p_args object contains a "displayStyle" member that defines how you want to display this object (using CSS styles, this will normally be "block" for a div, but may also be "inline" or other values of CSS's "display" property, just depending on what type of HTML element you bind to). I've defined two publicly exposed methods (defined as "this.Foo = function()", rather than "function Foo()") named "Show()" and "Hide()". These simply show or hide the parent HTML element (p_elSource) when called. The initialize() function just sets the "Loading..." text on p_elSource. You could get fancy and add an image here, or do other initialization stuff. Since this binding is so trivial, I have nothing to dispose and thus dispose() is empty.

    Now that you have a binding, how do you use it First, you need to make sure the binding's namespace is accessible to your gadget, so you add the following before the class that's going to use this binding:

    registerNamespace("ToddOs.Utils");

    That exposes the "ToddOs.Utils" namespace in which the LoadingPanel binding is defined. You can obviously use whatever namespace you wish to define your binding, and that's the namespace you should reference. I use "ToddOs.Utils" because my handle is "ToddOs" and this is a utility binding. Feel free to use your own namespace hierarchies.

    Once you've added the namespace, you need to create an HTML element and attach it to the binding. You can do this wherever you like, but you'll most likely do it in your gadget's initialize() or in a helper function called by initialize().

    var loadingContainer = document.createElement("div");
    p_elSource.appendChild(m_loadingContainer);

    m_loadingPanel = Web.Bindings.attachElementBindingSync(
    loadingContainer
    , ToddOs.Utils.LoadingPanel
    , m_this
    , {
    displayStyle:
    "block"
    });

    m_loadingPanel.Hide();

    // Clear the reference to loadingContainer
    loadingContainer = null;

    A couple of things to point out:

    • loadingContainer, the HTML element to which I attach the binding, is a local variable. I don't need to hang onto a reference to this, because any hiding or showing will be done through the binding. To avoid memory leaks, I release the reference (set the variable to null) after I'm done using the variable. The binding itself will hold onto a reference of that element until it's disposed, but that's okay.
    • I appended loadingContainer to p_elSource, but you could append it to another HTML element instead. At that point in the code, you're just building up your HTML DOM, so do whatever works for you. You can create loadingContainer as a span element, a paragraph element, an anchor element, a list item, a table cell, or anything else that can contain text. Just make sure you adjust your displayStyle appropriately (for example, a span should use "inline")
    • m_loadingPanel, the variable that actually contains the binding, is a class-level variable. I want to keep a reference to this so I can show or hide the loading panel later, so it's not local and it doesn't get cleared until the gadget or binding this code is in gets disposed.
    • I pass in displayStyle as an anonymous object.
    • m_this is just a reference to this that I set earlier to have a convenient self reference to the class without worrying about scoping issues.
    • After attaching the binding, I immediately call Hide() to hide it. That's just particular to my usage of the LoadingPanel, and you might want to work with it differently.
    • I didn't bother setting a class on loadingContainer because it'll get a class name from the binding itself. It'll be named "ToddOs_Utils_LoadingPanel", and you can reference that in your CSS (as I will show below).

    Now that you have your binding, you can call Show() or Hide() on m_loadingPanel whenever you need to show or hide your loading text. Once you're totally done with your binding (which will probably be in your dispose() method), you need to dispose it and clear the variable to null. I'm not going to show that here since it should be self-explanatory.

    If you want to style your LoadingPanel bindings, you can use CSS to do so:

    .ToddOs_Utils_LoadingPanel
    {
    display: none;
    color: #FFFFFF;
    min-height: 16px;
    }

    That's just a sample of what I've used. You can style your panel however like. Notice that I set the initial display state to "none". That makes my "Hide()" call above redundant, but that doesn't bother me much. You can do whatever you like.

    You can do a lot more than this with bindings, and they really come into their own whenever you start exposing events (see the SDK for info). As I've mentioned multiple times, this is just a very simple binding that works well as an example (though it is one I've used several times in real gadgets). Even though this functionality is trivial, it is nice to separate it out into a binding in case I want to change how I do loading screens later. For example, if I wanted to add a nice little animated gif next to the loading text, I could do that once in the binding and it would affect everywhere I use the binding. It also provides me with a pre-built solution for loading screens that I can use in other gadgets with very little effort (maybe some CSS tweaks).

    Feel free to use this binding in your own code (you'll need to copy it out to a js file and reference that file in your gadget.xml manifest). Also feel free to use it as a starting point for other bindings, add to it, change it, or otherwise mangle the code. You don't even need to attribute it to me :)


  • Sen_p_kumar

    Raros wrote:

    Thanks ToddOs for your reply...I understand "bindings" little bit now.... But I am still confused when can I use my own bindings using "attachbindingsbysync".

    I would definitely like to see more examples if you can provide.

    You attach your bindings any time you're ready to use them. If you're familiar with object oriented programming languages like C++, Java, or C#, think of attachElementBindingSync() as a constructor for the binding. By calling it, you instantiate that binding and call its initialize() method that initializes the binding. The parameters to the method provide the HTML element to which you're binding (usually you'll just create a div for this), the name of your binding (ie, "ToddOs.Utils.LoadingScreen"), the parent binding (just use this or m_this if you set an m_this), and an object containing parameters. You can pass in any object you like for this, which usually ends up being an anonymous object (like {param1: 123, param2: "abc", param3: someVar}).

    I'll try to pull together a few simple examples of bindings I've written.


  • hmayer

    Thanks for a very understandable and informative post, ToddOS.

    There is one thing that I wonder: this is the way to create a binding to an DOM object which is loadingContainer in your example.

    What I'd like to build is the common object to process some functions not relate to DOM object (kinda my own library to reuse later). Is this still applicable way

    If I try to replace loadContainer in Web.Bindings.attachElementBindingSync by null. Will it still work or need another approach

    Thanks,

    Bao Nguyen



  • smarr

    A binding is bound to a DOM element (thus "binding"). If you don't want to bind to a DOM element, you just want a normal javascript class. Just build that in the normal javascript way (but with a namespace like everything else). When you want to instantiate that class, create it with the standard "new" operator.
  • Julenka

    Thanks for sharing the example....


  • harlequinben

    Thanks ToddOs for your reply...I understand "bindings" little bit now.... But I am still confused when can I use my own bindings using "attachbindingsbysync".

    I would definitely like to see more examples if you can provide.


  • attachElementBindingSync