`
since1027
  • 浏览: 9723 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Part 3: More about Backbone Models

阅读更多
In this article we will look at some more concepts related to backbone models. We will try to see how we can override the default model behavior. We will look at the signification of model IDs, how we can validate a model and finally how a model can be persisted either locally or on a server.

Link to complete series:


The Initialize function and the Constructor

Whenever we create a model, the backbone will call its initialize function. We can override this function to provide custom behavior to it.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    initialize: function () {
        console.log('Book has been intialized');       
    },
});


So when we create this object the output will be:



Internally what happens is that whenever a backbone model is created, its constructor gets called. The constructor will call the initialize function. It is also possible to provide out own constructor and provide the custom behavior.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    initialize: function () {
        console.log('Book has been intialized');       
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
    },
});

The output when creating this model:



Now the problem with this constructor is that whenever the backbone model is getting created our constructor will be called. But the default constructor also does a lot of other activities at the time of object construction like calling the initialize function. So to make sure that our custom constructor works in unison with all that default behavior we need to let the backbone framework know that we still wants that default behavior. This can be done by calling Backbone.Model.apply(this, arguments); at the end of our custom constructor. This will make sure that our custom constructor will be called and then all the other activities that the default constructor is supposed to do are also done.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    initialize: function () {
        console.log('Book has been intialized');       
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
        Backbone.Model.apply(this, arguments);
    },
});

Now the output will be:



Note: For most of practical purposes overriding the initialize function will suffice. There is seldom a need to override the constructor but in case one decide to override the constructor, this should be the way to do it.

Model identifiers – id, cid and idAttribute

Every model needs to be uniquely identified. For this backbone gives us the model identifiers. The first one to look at is the cid. The cid or the client id is the auto-generated by backbone so that every model can be uniquely identified on the client.

var book1 = new Book();
var book2 = new Book();



Backbone also provides an identifier id to uniquely identify the model entity. This is the id that will be used to identify the model when the model data is actually being synced with server i.e. getting persisted. the cid is more useful for debugging purpose but the id attribute will determine the uniqueness of the model when it comes to CRUD operations on the model. Its fairly straight forward to set and get the id property.

var book2 = new Book();
book2.id = 3;
console.log(book2.id);

Output for the above code will be: 3.

Now it gets a little confusing at this point. Since most of our models will have an attribute that will correspond to the primary key/unique identifier of the entity. Do we need to explicitly set the id value to that attribute. The answer if yes and no. We have to somehow indicate the backbone model what attribute should be used as id but we don’t have to set the id explicitly. we can use the idAttribute to accomplish this.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    idAttribute: "ID",
    initialize: function () {
        console.log('Book has been intialized');
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
        Backbone.Model.apply(this, arguments);
    },
});


Now in the above code we have specified that the ID should be used as id by specifying the idAttribute. Lets try to create a new model with ID value now.

var book3 = new Book({ ID: 43 });
console.log(book1.id);

And we can see that the id value is taken from the specified attribute.



and thus this makes it very easier for the backbone models to work with server side entities and makes the model identification seamless.

Validating the model

When we are working on business applications it is often required that we validate the model before persisting the data. Backbone provides a very easy way of validating the model data. We just need to implement the models validate function.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    idAttribute: "ID",
    initialize: function () {
        console.log('Book has been intialized');
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
        Backbone.Model.apply(this, arguments);
    },
    validate: function (attr) {
        if (attr.ID <= 0) {
            return "Invalid value for ID supplied."
        }
    }
});

What happens here is that whenever we try to save the model(which we will see in next section), the Validate function will get called. It will check the custom
validation logic that we have put in place and validate the model. To test the validate method, we can use models isValid function.

var book4 = new Book({ ID: -4 });
var result = book4.isValid(); // false

Another way to prevent the invalid values in the model attributes is by passing the validate:true while setting the models attribute. This will also trigger the validate function

var book5 = new Book();
book5.set("ID", -1, {validate:true});

What this will do is that this will not even allow setting of invalid values if the value that we are trying to set is invalid as per our custom logic.

How this validation works is that whenever the user chooses to save the model, the validate function will be called. if there is any validation error then the model save will fail. alternatively, the user can choose to pass validate:true whenever he want to restrict the setting of invalid values in the model attributes.

If we want to check the validity of the model at any particular instance, we can use the isValid function to test this. Having said that one important thing to know here is that whenever our validation function fails to validate the model an event invalid is raised by backbone. If we want to listen to this event, we can subscribe to this.

Lets try to hook up to this event and see the validation errors. We will do this in the initialize function of the model.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    idAttribute: "ID",
    initialize: function () {
        console.log('Book has been intialized');
        this.on("invalid", function (model, error) {
            console.log("Houston, we have a problem: " + error)
        });
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
        Backbone.Model.apply(this, arguments);
    },
    validate: function (attr) {
        if (attr.ID <= 0) {
            return "Invalid value for ID supplied."
        }
    }
});




Saving the model

The backbone models inherently supports saving on the server using a restful web api. To save the model using a HTTP REST service, we need to specify the  urlRoot in the backbone model. To actually save the model, we can call the save on the backbone model. The save method will trigger the validations and if the validations are successful, it will try to identify the action to be performed i.e. create or update and based on that action, it will use  urlRoot and call the appropriate REST API to perform the operation.

So if I have a service running on my local machine, i first need to specify the urlRoot for the service in my model.

var Book = Backbone.Model.extend({
    defaults: {
        ID: "",
        BookName: ""
    },
    idAttribute: "ID",
    initialize: function () {
        console.log('Book has been initialized');
        this.on("invalid", function (model, error) {
            console.log("Houston, we have a problem: " + error)
        });
    },
    constructor: function (attributes, options) {
        console.log('Book\'s constructor had been called');
        Backbone.Model.apply(this, arguments);
    },
    validate: function (attr) {
        if (attr.ID <= 0) {
            return "Invalid value for ID supplied."
        }
    },
    urlRoot: 'http://localhost:51377/api/Books'
});

and to save this model using this service, I could do something like:

var book = new Book({ BookName: "Backbone Book 43" });
    book.save({}, {
        success: function (model, response, options) {
            console.log("The model has been saved to the server");
        },
        error: function (model, xhr, options) {
            console.log("Something went wrong while saving the model");
        }
    });

The save function also accepts success and error callback functions so that appropriate action can be taken based on the response from the server.

Now if we want to save the model on local storage rather than on a server, we just need to keep in mind that save function actually calls sync function to actually save/retrieve the model information. So if we need to save the model on a local storage, we need to override the sync function and provide the custom code to save on local storage.

Note: The code shown above(for save model) is syntactically correct but it will not work unless we have a REST service running at mentioned urlRoot. In coming articles, I will explain the model save using the REST service in details along with the sample service and HTML code.

Point of interest

So we saw a few more details about the backbone models. We have not yet looked at how to save the model either locally or via using a service. Perhaps in my next articles, we will talk about that only.

原文链接:http://rahulrajatsingh.com/2014/07/backbone-tutorial-part-3-more-about-backbone-models/
分享到:
评论

相关推荐

    Part 2: Understanding the basics of Backbone Models

    在本文中,我们将深入理解Backbone Models的基本概念,这是Backbone框架的核心组件之一。 **Backbone Models** Backbone Models是数据的容器,它们负责存储应用程序中的数据和业务逻辑。模型通常与服务器上的数据...

    JavaScriptMVC框架PK:Angular、Backbone、CanJS与Ember

    本文对JavaScriptMVC框架Angular、Backbone、CanJS和Ember作了比较,供大家参考。选择JavaScriptMVC框架很难。一方面要考虑的因素非常多,另一方面这种框架也非常多,而要从中选择一个合适的,还真得费一番心思。想...

    pets:试验一下backbone.js

    在本项目中,标题"pets:试验一下backbone.js"表明我们将探讨如何使用Backbone.js这一JavaScript库来创建一个宠物相关的应用。Backbone.js是一个轻量级的框架,它为构建复杂的JavaScript应用程序提供了模型-视图-视图...

    《Node应用程序构建:使用MongoDB和Backbone》 源码

    3. **Backbone.js**:Backbone.js是一个轻量级的JavaScript库,用于构建富客户端应用。它提供模型-视图-收藏夹(MVC)架构,帮助组织代码,使应用逻辑更清晰。Backbone.js的核心特性包括双向数据绑定、RESTful JSON...

    backbone-mixins:用于 Backbone 应用程序的 mixin 集合

    用于 Backbone 应用程序的 mixin 集合 Backbone.Mixins.RouteFilter 将“before:route:whatever”或“after:route:whatever”过滤器添加到主干路由器 使用 before 过滤器异步收集数据的示例: class TodosRouter ...

    mast:建立在Backbone.JS之上的UI约定

    Mast带来了来自诸如Knockout和Angular之类的框架的一些更重要的贡献,并允许您使用Backbone Models,Collections和Views来利用它们,并着眼于为中型到大型团队进行切实有效的开发。 它并非旨在取代Angular之类的...

    TODO-APP:使用Backbone.js开发ud989的项目

    **Backbone.js 框架详解** Backbone.js 是一个轻量级的JavaScript库,它为Web应用提供了模型-视图-控制器(MVC)架构模式。在"TODO-APP: 使用Backbone.js开发ud989的项目"中,我们将深入探讨如何利用Backbone.js...

    webui-comic:SPA使用backbone.js

    3. **模型(Models)**:Backbone.js中的模型封装了业务逻辑和数据,它们可以监听并响应变化,自动同步到视图,反之亦然。这使得数据和界面保持一致。 4. **视图(Views)**:视图负责处理用户交互,渲染HTML,并...

    backbone.transceiver:简化使用 Backbone.Radio 的 Backbone 插件

    这是一个 Backbone 插件,它简化了 Backbone.Radio 在 Marionette 应用程序中的使用。 它允许使用简单的语法以声明方式配置事件、请求和命令: var MyApplication = Marionette.Application.extend({ channels: {...

    Java 演示 backbone 基本用法

    3. **Backbone.Collection**: Collection是Model的集合,它扩展自Array对象,提供了对一组数据进行操作的功能,如排序、过滤等。Collection也拥有自己的Model事件,当集合中的某个模型发生变化时,可以触发相应事件...

    promisable-models:Promisable Models 是 Backbone Models 和 Collection 的混合体,允许它们表现得像 jQuery Promises

    模型和集合是每个 Backbone/Marionette 应用程序的重要组成部分。 这个 Marionette 模块允许模型和集合作为 jQuery Promises 运行,从而消除跟踪从 ajax 调用返回的 XHR 对象的需要。 Promisable Models 可用于例如...

    mybackbone-react-ui:我的Backbone+react练习UI

    2. `models`: Backbone的模型定义,用于存储和管理数据。 3. `collections`: 一组相关的模型实例,方便批量操作和管理。 4. `views`: Backbone的视图,负责与用户交互和更新视图。 5. `components`: React的组件定义...

    backbone-parse:一个 Backbone 插件,使其与 Parse.com 一起开箱即用

    骨干解析覆盖 Backbone.Sync 方法以使用其 REST API 自动将您的骨干模型保存在 Parse 上。 使您免于所有手动管道。 安装 步骤1: 下载backbone-parse.js 并在backbone.js 之后包含在你的应用程序中,例如 &lt; ...

    backbone-pizza:使用一些 Backbone 元素的简单测试

    1. **Models**:这是数据的容器,通常与服务器上的JSON资源对应。Model负责处理数据的验证、同步和事件触发。 2. **Collections**:是Model的集合,提供了操作和管理一组数据的方法,如排序、过滤等。 3. **Views*...

    第P9周:YOLOv5-Backbone模块实现

    第P9周:YOLOv5-Backbone模块实现

    laravel-backbone-presentation:Laravel 和 Backbone 工作流

    **Laravel 和 Backbone 工作流** 在现代Web开发中,Laravel 和 Backbone.js 是两个非常重要的工具。Laravel 是一个基于PHP的优雅且强大的Web应用框架,而Backbone.js 是一个轻量级的JavaScript库,用于构建客户端的...

    前端项目-backbone.radio.zip

    3. **消息传递模式**:在Backbone.Radio中,消息传递模式通过`Radio.channel`来实现。开发者可以创建频道,发布和监听消息,从而实现组件间的解耦通信。 4. **频道(Channel)**:Backbone.Radio的核心是频道概念,...

    BackBone介绍及使用

    **BackBone介绍** Backbone.js 是一款轻量级的JavaScript框架,主要用来构建富客户端的Web应用。它强调数据模型的管理和视图的同步,帮助开发者以更有序的方式组织前端代码,提高开发效率。Backbone.js的核心设计...

Global site tag (gtag.js) - Google Analytics