2
votes

To all the Ti Alloy experts out there:

There are a couple of questions out there already dealing with this same problem, none of them marked with an accepted answer and certainly none answered to my personal satisfaction. Let me explain why I still believe the problem is relevant, existing answers and comments notwithstanding:

In Alloy, you are allowed to bind repeater-type elements to models in a Backbone collection; this is straightforward enough and works beautifully. However, in a typical master-detail view arrangement you may wish to bind a view to a specific model instance, which you have passed into the controller for this purpose.

As far as I've been able to make out the standard Alloy technique for this seems to be that you declare a model instance in the Alloy markup, eg. <Model id="myModelInstance" src="myBackboneModel" instance="true"> and then proceed to work with this model in the controller code by way of $.myModelInstance... references.

The problem arises when you have passed your own model instance into the controller, as you are unable to "point" the declared view model instance to your existing model instance. You must instead "copy" your model attributes to the view's model instance by doing

$.myModelInstance.set(myPassedInModel.attributes);

This works well enough in practice, but requires that you marshall changes to the view model back to the "real" model that was passed in, and is also inconvenient if the view is to be responsive to changes in the underlying collection.

Am I missing something here, or is there perhaps a better solution I'm not aware of?

Any feedback or insights will be much appreciated.

Cheers, Francois.

1
Can you instead pass the "model" as an argument in the creation of the View / Controller? This way you are always working with the same model (and no marshalling of data in two directions)Josiah Hester
If you pass the model in as a regular controller argument, you only have the option to set it into the view as I described in my question. Trying the $model hack you described in one of your other comments does not (or at least no longer seems to) work - this is as tested against 3.2.3.GA with alloy 1.3.1. Any other suggestions?quasi-aussie
Have you ever figured out a better way of doing it? It is unbelieveable that there are not a single example if doing this on docs or forums.Fernando Fabreti

1 Answers

0
votes

I see that this question is now about a year and half old, but for posterity I will offer my preferred solution: Instead of using an instance, use a singleton for the detail view and set the model data globally. A simple example:

// alloy.js
// initialize the model on app start
var detailModel = Alloy.Models.instance('myModel');

// repeater.xml
<Button title='Show Detail' onClick='showDetail' />

// repeater.js
function showDetail() {
    Alloy.Models.myModel.clear();
    Alloy.Models.myModel.set($.model.toJSON());
    navigateToDetailView();
}

// detail.xml
// access global singleton in your detail view
<Alloy>
    <Model src='myModel' />
    <Window title='{myModel.title}' >
        <Label text='{myModel.description}' />
    </Window>
</Alloy>

Note that to do this, your repeater must have its own controller (use Require element) as best I can tell. I don't think this is significantly different than the solution offered in the question, but I think it is simpler.