2

I am new to Titanium Alloy, the MVC framework, and Backbone.js, so I'm having a little trouble wrapping my head around some of the concepts.

Similar questions have been asked previously:

Getting ID of clicked TableRow in Titanium Alloy?

Appcelerator Titanium Alloy: How to store data on a ScrollableView to use in click event

but, though I am trying to follow the answers, I just cannot seem to get the following code to work as expected.

Basically, when data binding in Titanium Alloy, how do you pass the current model to the controller?

(Also, this is my first question on here, so if there is any area in which I could improve my query please let me know, thanks).

Model

exports.definition = {
config: {
    columns: {
        "issueNo": "number",
        "date": "string",
        "summary": "string",
        "cover": "string"
    },
    adapter: {
        type: "sql",
        collection_name: "issue"
    }
},
extendModel: function(Model) {
    _.extend(Model.prototype, {
        // extended functions and properties go here
    });

    return Model;
},
extendCollection: function(Collection) {
    _.extend(Collection.prototype, {
        // extended functions and properties go here
    });

    return Collection;
}
};

View

<Alloy>
<Collection src="issue" />
<Window class="container" onClose="cleanup">
    <View id="header">
        <Label id="title">Christian</Label>
    </View>
    <View id="library" class="body" layout="vertical" dataCollection="issue">
        <View id="issuesList" model="{alloy_id}" onClick="alertModel">
            <ImageView id="cover" image="{cover}"></ImageView>
            <Label id="date" text="{date}"></Label>
            <Label id="summary" text="{summary}"></Label>
            <View class="border"></View>
        </View>
    </View>
    <View id="store" class="body" layout="vertical" visible="false" backgroundColor="yellow">

    </View>
    <View id="footer">
        <TabbedBar id="bottomNav" platform="ios" index="0" onClick="viewSelect">
            <Labels>
                <Label>Library</Label>
                <Label>Store</Label>
            </Labels>
        </TabbedBar>
    </View>
</Window>
</Alloy>

Controller

var Newsstand = require("ti.newsstand");
Newsstand.enableDevMode();

var issues = Alloy.Collections.issue;
issues.fetch();

var issue1 = Alloy.createModel("issue", {
    issueNo: 1,
    date: "1/1/2014",
    summary: "Some text.",
    cover: "/issues/cover_1.png"
});

var issue2 = Alloy.createModel("issue", {
    issueNo: 2,
    date: "1/2/2014",
    summary: "Some text.",
    cover: "/issues/cover_2.png"
});

var issue3 = Alloy.createModel("issue", {
    issueNo: 3,
    date: "1/3/2014",
    summary: "Some text.",
    cover: "/issues/cover_3.png"
});

issues.add(issue1);
issues.add(issue2);
issues.add(issue3);


function viewSelect(tabbedBar) {
    var index = tabbedBar.index,
        library = $.library,
        store = $.store,
        bottomNav = $.bottomNav;

    if (index === 0) {
        library.visible = true;
        store.visible = false;
    } else {
        store.visible = true;
        library.visible = false;
    }
}

function alertModel(e){
    var modelId = e.model,
        model = issues.get(modelId),
        issueNumber = model.get("issueNo");

    alert(issueNumber);
}

function cleanup() {
    $.destroy();
}

$.index.open();
Community
  • 1
  • 1
curzmg
  • 647
  • 6
  • 11

1 Answers1

1

Updated answer based on comment from OP:

On the second link you posted, if binding data to Views it says you need to set touchEnabled="false" on all of the elements in the view template and then use e.source.model in your alertModel function. Tested and it works for me.

var modelId = e.source.model,
        model = issues.get(modelId),
        issueNumber = model.get("issueNo");

I always use ListViews to bind my data and you don't need to explicitly set touchEnabled when using those.

Additionally, the alloy_id doesn't get created until you save a model to the DB. Calling .add() on your collection doesn't save it, you have to call .save() on your model to have it saved.

Sample here: https://github.com/foolprooflabs/testforcurzmg

phil
  • 1,940
  • 1
  • 13
  • 13
  • Thanks phil for the quick response. Perhaps I didn't quite explain myself well enough. The problem at the moment is that the model is not being passed to the controller. I am getting the error "'undefined' is not an object (evaluating 'model.get')", which I presume means that the model isn't being passed correctly. I've noticed that even if I simply alert e.model then the dialog comes up empty, so I think the problem might have something to do with e.model being wrong, but I'm not sure. – curzmg Oct 03 '14 at 16:03
  • ok np, i updated the answer. The answer was in the second link you posted :P – phil Oct 06 '14 at 00:33
  • Thanks again phil, but it still doesn't appear to be working. Again, if I try to alert just e.source.model I am getting an empty dialog, and this seems to be resulting in a failure to get the model from the collection. This is despite the fact that the touch disabled is definitely working, as I've had a look at e.source. When does Titanium add the alloy_id, perhaps its an order thing? Could you possibly post your working code for me, if you still have it, as I might recognise a difference. I appreciate the help. – curzmg Oct 06 '14 at 15:14
  • yeah sorry I missed an important point in my code, the alloy_id of a model only gets created if the model is saved to the database (adding to the collection doesn't save it to the db) so after you call .add(issue1) (or even instead of), you should call issue1.save(). Github link to sample project here: https://github.com/foolprooflabs/testforcurzmg (still uploading now as I comment) – phil Oct 06 '14 at 23:39
  • Ah, that's done it! Thank you phil, you've been very helpful. I am just marking the question as solved now. – curzmg Oct 07 '14 at 14:53