Sencha touch 如何从Sencha Touch 2中的simple app.js创建MVC

Sencha touch 如何从Sencha Touch 2中的simple app.js创建MVC,sencha-touch,extjs,sencha-touch-2,Sencha Touch,Extjs,Sencha Touch 2,我有一个简单的登录表单,在正确登录后,它会滑到下一个视图。我发现的两个例子的组合。我想使用MVC模式将这个登录分为几个文件。在我在网上看到的许多例子中,这在SenchaTouch2中是小菜一碟。不管我怎么做,我都不能让它工作。我习惯用Flex、Java、ActionScript、Php编程,但Sencha jSon完全是另一回事。有人能帮我吗?我希望在推荐的文件夹结构中有一个模型、存储、视图和控制器包: -app -controller -Controller.js -model

我有一个简单的登录表单,在正确登录后,它会滑到下一个视图。我发现的两个例子的组合。我想使用MVC模式将这个登录分为几个文件。在我在网上看到的许多例子中,这在SenchaTouch2中是小菜一碟。不管我怎么做,我都不能让它工作。我习惯用Flex、Java、ActionScript、Php编程,但Sencha jSon完全是另一回事。有人能帮我吗?我希望在推荐的文件夹结构中有一个模型、存储、视图和控制器包:

-app
  -controller
    -Controller.js
  -model
    -Model.js
  -store
    -Store.js
  -view
    -Main.js
    -Login.js
    -SecondView.js
-app.js
-app.css
-index.html
这是当前的app.js,在一个文件中包含所有逻辑

Ext.require([
'Ext.form.Panel',
'Ext.form.FieldSet',
'Ext.field.Text',
'Ext.field.Password',

'Ext.data.Store'
]);

Ext.define('User', {
extend: 'Ext.data.Model',

config: {
    fields: [
        {name: 'name', type: 'string'},
        {name: 'password', type: 'string'}
    ]
}
});

Ext.setup({
icon: 'icon.png',
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
glossOnIcon: false,
onReady: function() {
    var form;

    var formBase = {
        url: 'login.php',
        standardSubmit: false,
        title:"Login",
        items: [
            {
                xtype: 'fieldset',
                title: 'MyCompony',
                instructions: 'Log in with username and password.',
                defaults: {
                    required: true,
                    labelAlign: 'left',
                    labelWidth: '40%'
                },
                items: [
                    {
                        xtype: 'textfield',
                        name: 'name',
                        label: 'Name',
                        value: 'user',
                        autoCapitalize: false
                    },
                    {
                        xtype: 'passwordfield',
                        name: 'password',
                        label: 'Password',
                        value: 'test'
                    }
                ]
            },
            {
                xtype: 'toolbar',
                docked: 'bottom',
                items: [
                    {xtype: 'spacer'},
                    {
                        text: 'Reset',
                        handler: function() {
                            form.reset();
                        }
                    },
                    {
                        text: 'Login',
                        ui: 'confirm',
                        handler: function() {
                            if (formBase.user) {
                                form.updateRecord(formBase.user, true);
                            }
                            form.submit({
                                waitMsg: {message: 'Submitting'}
                            });
                        }
                    }
                ]
            }
        ],

        listeners: {
            submit: function(form, result) {
                console.log('success', Ext.toArray(arguments));
                view.push({
                    title: 'Second View',
                    padding: 10,
                    items: [
                        {
                            html: 'Second view'
                        },
                        {
                            xtype: 'button',
                            text: 'Pop this view!',
                            width: 200,
                            handler: function() {
                                view.pop();
                            }
                        }
                    ]
                });
            },
            exception: function(form, result) {
                console.log('failure', Ext.toArray(arguments));
            }
        }
    };

    if (Ext.os.deviceType == 'Phone') {
        Ext.apply(formBase, {
            xtype: 'formpanel',
            autoRender: true
        });
    } else {
        Ext.apply(formBase, {
            xtype: 'formpanel',
            autoRender: true,
            padding: 100
        });
    }
    form = Ext.create('Ext.form.Panel', formBase);
    var view = Ext.create('Ext.navigation.View', {
        fullscreen: true,
        items: [
            form
        ]
    });

}
});
这是一个简单的php脚本login.php,用于响应登录请求

<?php
$pw = $_REQUEST['password'];
header('Content-Type: application/json');
if($pw == 'asdf'){
    echo '{"success":true, "msg":'.json_encode('This User is authorized').'}';
}else{
    echo '{"success":false, "msg":'.
        json_encode('This User is NOT authorized').
        ', "errors" : { "password" :'.json_encode('Password is required').
        '}'.
        ', "pwd" :'.json_encode($pw).'}';
}

有人吗?

我强烈建议您观看此视频,了解Sencha Touch 2中的MVC应用程序


本视频提供了一个处理表单的示例,您可以根据自己的情况应用这些表单。

我强烈建议您观看本视频,了解Sencha Touch 2中的MVC应用


本视频提供了一个处理表单的示例,您可以根据自己的情况应用这些表单。

MVC的整个要点就是分解逻辑。我说不出在app.js中保留所有逻辑有什么错。但是在看了各种例子之后,我了解到app.js是一个短文件,而不是一个大文件。将逻辑部分移动到各种其他文件控制器逻辑到controller.js和all,然后重试。 我可以很快指出的一个例子是以下代码

var formBase = {
    url: 'login.php',
    standardSubmit: false,
    title:"Login",
    items: [
        {
            xtype: 'fieldset',
            title: 'MyCompony',
            instructions: 'Log in with username and password.',
            defaults: {
                ...
            },
            items: [
                {
                    xtype: 'textfield',
                    ...
                },
                {
                    xtype: 'passwordfield',
                    ...
                }
            ]
        },
        {
            xtype: 'toolbar',
            ...
            items: [
                {xtype: 'spacer'},
                {
                    ...
                },
                {
                    text: 'Login',
                    ...
                    handler: function() {
                        ...
                    }
                }
            ]
        }
    ],
应该在view.js中。
这就是MVC的意思。希望它能回答您的问题。

MVC的全部目的就是打破逻辑。我说不出在app.js中保留所有逻辑有什么错。但是在看了各种例子之后,我了解到app.js是一个短文件,而不是一个大文件。将逻辑部分移动到各种其他文件控制器逻辑到controller.js和all,然后重试。 我可以很快指出的一个例子是以下代码

var formBase = {
    url: 'login.php',
    standardSubmit: false,
    title:"Login",
    items: [
        {
            xtype: 'fieldset',
            title: 'MyCompony',
            instructions: 'Log in with username and password.',
            defaults: {
                ...
            },
            items: [
                {
                    xtype: 'textfield',
                    ...
                },
                {
                    xtype: 'passwordfield',
                    ...
                }
            ]
        },
        {
            xtype: 'toolbar',
            ...
            items: [
                {xtype: 'spacer'},
                {
                    ...
                },
                {
                    text: 'Login',
                    ...
                    handler: function() {
                        ...
                    }
                }
            ]
        }
    ],
应该在view.js中。
这就是MVC的意思。希望它能回答你的问题。

好的,经过几天的研究,以下是答案:

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Map</title>
    <link rel="stylesheet" href="../../resources/css/sencha-touch.css" type="text/css">
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script type="text/javascript" src="../../builds/sencha-touch-all-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>
werkorders.json

[
    {
        "id": "14",
        "lastName": "Franklin",
        "latitude": "52.370216",
        "longitude": "4.895168"
    },
    {
        "id": "2",
        "lastName": "Johnson",
        "latitude": "52.370316",
        "longitude": "4.895868"
    },
    {
        "id": "8",
        "lastName": "Vanderburg",
        "latitude": "52.370516",
        "longitude": "4.895968"
    }
]
app/view/Main.js:

Ext.define('AddressBook.view.Main', {
    extend: 'Ext.navigation.View',
    xtype: 'mainview',

    requires: [
        'AddressBook.view.Login',
        'AddressBook.view.workorder.Map',
        'AddressBook.view.workorder.Edit'
    ],

    config: {
        autoDestroy: false,

        navigationBar: {
            ui: 'sencha',
            items: [
                {
                    xtype: 'button',
                    id: 'editButton',
                    text: 'Edit',
                    align: 'right',
                    hidden: true,
                    hideAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeOut',
                        duration: 200
                    },
                    showAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeIn',
                        duration: 200
                    }
                },
                {
                    xtype: 'button',
                    id: 'saveButton',
                    text: 'Save',
                    ui: 'sencha',
                    align: 'right',
                    hidden: true,
                    hideAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeOut',
                        duration: 200
                    },
                    showAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeIn',
                        duration: 200
                    }
                }
            ]
        },

        items: [
            { xtype: 'loginForm' }
        ]
    }
});
app/view/Login.js:

Ext.define('AddressBook.view.Login', {
    title: "Luminizer Login",
    extend: 'Ext.form.Panel',
    xtype: 'loginForm',

    config: {
        url: 'login.php',
        standardSubmit: false,
        title: 'Login Luminizer',
        layout: 'vbox',
        items: [
            {
                xtype: 'fieldset',
                title: 'MyCompony',
                instructions: 'Log in with username and password.',
                defaults: {
                    required: true,
                    labelAlign: 'left',
                    labelWidth: '40%'
                },
                items: [
                    {
                        xtype: 'textfield',
                        name: 'username',
                        id: 'username',
                        label: 'Name',
                        value: 'user',
                        autoCapitalize: false
                    },
                    {
                        xtype: 'passwordfield',
                        name: 'password',
                        id: 'password',
                        label: 'Password',
                        value: 'test'
                    }
                ]
            },
            {
                xtype: 'toolbar',
                docked: 'bottom',
                items: [
                    {xtype: 'spacer'},
                    {
                        text: 'Reset',
                        handler: function() {
                            var form = this.parent.parent;
                            form.reset();
                        }
                    },
                    {
                        text: 'Login',
                        ui: 'confirm',
                        handler: function() {
                            var form = this.parent.parent;

                            var username = form.getValues().username;//form.down('#username').getValue();
                            var password = form.getValues().password;//down('#password').getValue();
                            form.fireEvent('login', username, password);
                        }
                    }
                ]
            }
        ]
    },

    resetForm: function() {
        var view = this.parent;
        view.down("#username").setValue("");
        view.down("#password").setValue("");
    }
});
app/view/workorder/map.js:

Ext.define('AddressBook.view.workorder.Map', {
    extend: 'Ext.Panel',
    xtype: 'map-show',
    requires: [
        'Ext.Map'
    ],
    config: {
        title: 'Information',
        layout: 'card',
        items: [
            {
                xtype: 'map',
                mapOptions : {
                    zoom : 15,
                    mapTypeId : google.maps.MapTypeId.ROADMAP,
                    navigationControl: true,
                    navigationControlOptions: {
                        style: google.maps.NavigationControlStyle.DEFAULT
                    }
                }
            }
        ]
    },

    centerMap: function(newRecord) {
        if (newRecord) {
            this.down('map').setMapCenter({
                latitude: newRecord.data.latitude,
                longitude: newRecord.data.longitude
            });
        }
    },

    setMarkers: function(markers) {
        var mapPanel = this;
        var map = this.down("map")._map;
        mapPanel.markerDataDict = {};
        mapPanel.markerDict = {};


        if(!mapPanel.infowindow) {
            mapPanel.infowindow = new google.maps.InfoWindow({
                content: 'Sencha HQ'
            });
        }
        for(var i = 0 ;i < markers.length; i++) {
            var markerData = markers[i];
            map.setZoom(15);
            var latitude = Number(markerData.data.latitude);
            var longitude = Number(markerData.data.longitude);
            var position = new google.maps.LatLng(latitude, longitude);
            mapPanel.markerDataDict[position] = markerData;
            var marker = new google.maps.Marker({
                position: position,
                title : markerData.data.id,
                map: map
            });
            mapPanel.markerDict[position] = marker;

            google.maps.event.addListener(marker, 'click', function(mouseEvent) {
                var lat = Math.round(mouseEvent.latLng.lat() * 1000000)/1000000;
                var lng = Math.round(mouseEvent.latLng.lng() * 1000000)/1000000;
                var id = mapPanel.markerDataDict[mouseEvent.latLng].data.id;
                mapPanel.infowindow = new google.maps.InfoWindow();
                mapPanel.infowindow.setContent(['Werkorder: '+ id +'<br/>',
                                                'lat.:' + lat + '<br/>',
                                                'long.:' + lng ].join(""));
                if(mapPanel.oldInfowindow)
                    mapPanel.oldInfowindow.close();
                mapPanel.oldInfowindow = mapPanel.infowindow;
                mapPanel.infowindow.open(map, mapPanel.markerDict[mouseEvent.latLng]);
                mapPanel.infowindow.setPosition(mouseEvent.latLng);
                mapPanel.fireEvent('markerClicked', mapPanel.markerDataDict[mouseEvent.latLng])
            });
        }
    }
});
app/controller/AppController.js:

Ext.define('AddressBook.controller.AppController', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            main: 'mainview',
            editButton: '#editButton',
            contacts: 'contacts',
            loginForm: 'loginForm',
            showMap: 'map-show',
            editContact: 'contact-edit',
            saveButton: '#saveButton'
        },

        control: {
            main: {
                push: 'onMainPush',
                pop: 'onMainPop'
            },
            editButton: {
                tap: 'onContactEdit'
            },
            contacts: {
                itemtap: 'onMarkerSelect'
            },
            loginForm: {
                login: 'onLogin'
            },
            showMap: {
                markerClicked: 'onMarkerSelect'
            },
            saveButton: {
                tap: 'onContactSave'
            },
            editContact: {
                change: 'onContactChange'
            }
        }
    },

    onMainPush: function(view, item) {
        var editButton = this.getEditButton();

        if (item.xtype == "map-show") {
            this.getLoginForm().reset();

            this.showEditButton();
        } else {
            this.hideEditButton();
        }
    },

    onMainPop: function(view, item) {
        if (item.xtype == "contact-edit") {
            this.showEditButton();
        } else {
            this.hideEditButton();
        }
    },

    onMarkerSelect: function(record) {
        var editButton = this.getEditButton();

        if (!this.showEdit) {
            this.showEdit = Ext.create('AddressBook.view.workorder.Edit');
        }

        // Bind the record onto the show contact view
        this.showEdit.setRecord(record);

        // Push the show contact view into the navigation view
        this.getMain().push(this.showEdit);
    },

    onLogin: function(username, password) {
        var controller = this;
        Ext.Ajax.request({
            url: 'login.php',
            method: 'POST',
            disableCaching: true,

            params: {
                username: username,
                password: password
            },

            success: function(response) {
                console.log("Login successful for {username}");
                var editButton = controller.getEditButton();
                if (!controller.showContact) {
                    controller.showContact = Ext.create('AddressBook.view.workorder.Map');
                }

                var store = Ext.getStore("WorkOrders");
                store.load({callback: function(records, operation, success) {
                                if(success) {
                                    console.log(records);
                                    controller.showContact.centerMap(store.data.items[0]);
                                    controller.showContact.setMarkers(store.data.items);
                                    // Push the show contact view into the navigation view
                                    controller.getMain().push(controller.showContact);
                                    controller.getLoginForm().resetForm();
                                }
                            },
                            scope: this
                });

            },

            failure: function(response) {
                console.log("Login failure for {username}");
            }
        });

    },

    onMarkerClicked: function(markerData) {

    },

    onContactEdit: function() {
        if (!this.editContact) {
            this.editContact = Ext.create('AddressBook.view.workorder.Edit');
        }

        // Bind the record onto the edit contact view
        this.editContact.setRecord(this.getShowContact().getRecord());

        this.getMain().push(this.editContact);
    },

    onContactChange: function() {
        this.showSaveButton();
    },

    onContactSave: function() {
        var record = this.getEditContact().saveRecord();

        this.getShowContact().updateRecord(record);

        this.getMain().pop();
    },

    showEditButton: function() {
        var editButton = this.getEditButton();

        if (!editButton.isHidden()) {
            return;
        }

        this.hideSaveButton();

        editButton.show();
    },

    hideEditButton: function() {
        var editButton = this.getEditButton();

        if (editButton.isHidden()) {
            return;
        }

        editButton.hide();
    },

    showSaveButton: function() {
        var saveButton = this.getSaveButton();

        if (!saveButton.isHidden()) {
            return;
        }

        saveButton.show();
    },

    hideSaveButton: function() {
        var saveButton = this.getSaveButton();

        if (saveButton.isHidden()) {
            return;
        }

        saveButton.hide();
    }
});
app/model/WorkOrder.js:

Ext.define('AddressBook.model.WorkOrder', {
    extend: 'Ext.data.Model',

    config: {
        fields: [
            'id',
            'lastName',
            'latitude',
            'longitude'
        ]
    }
});
app/store/WorkOrders.js:

Ext.define('AddressBook.store.WorkOrders', {
    extend: 'Ext.data.Store',

    config: {
        model: 'AddressBook.model.WorkOrder',
        autoLoad: false,
        sorters: 'id',
        proxy: {
            type: 'ajax',
            url: 'werkorders.json',
            reader: {
                type: 'json'
            }
        }
    }
});

好的,经过几天的研究,以下是答案:

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Map</title>
    <link rel="stylesheet" href="../../resources/css/sencha-touch.css" type="text/css">
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script type="text/javascript" src="../../builds/sencha-touch-all-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>
werkorders.json

[
    {
        "id": "14",
        "lastName": "Franklin",
        "latitude": "52.370216",
        "longitude": "4.895168"
    },
    {
        "id": "2",
        "lastName": "Johnson",
        "latitude": "52.370316",
        "longitude": "4.895868"
    },
    {
        "id": "8",
        "lastName": "Vanderburg",
        "latitude": "52.370516",
        "longitude": "4.895968"
    }
]
app/view/Main.js:

Ext.define('AddressBook.view.Main', {
    extend: 'Ext.navigation.View',
    xtype: 'mainview',

    requires: [
        'AddressBook.view.Login',
        'AddressBook.view.workorder.Map',
        'AddressBook.view.workorder.Edit'
    ],

    config: {
        autoDestroy: false,

        navigationBar: {
            ui: 'sencha',
            items: [
                {
                    xtype: 'button',
                    id: 'editButton',
                    text: 'Edit',
                    align: 'right',
                    hidden: true,
                    hideAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeOut',
                        duration: 200
                    },
                    showAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeIn',
                        duration: 200
                    }
                },
                {
                    xtype: 'button',
                    id: 'saveButton',
                    text: 'Save',
                    ui: 'sencha',
                    align: 'right',
                    hidden: true,
                    hideAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeOut',
                        duration: 200
                    },
                    showAnimation: Ext.os.is.Android ? false : {
                        type: 'fadeIn',
                        duration: 200
                    }
                }
            ]
        },

        items: [
            { xtype: 'loginForm' }
        ]
    }
});
app/view/Login.js:

Ext.define('AddressBook.view.Login', {
    title: "Luminizer Login",
    extend: 'Ext.form.Panel',
    xtype: 'loginForm',

    config: {
        url: 'login.php',
        standardSubmit: false,
        title: 'Login Luminizer',
        layout: 'vbox',
        items: [
            {
                xtype: 'fieldset',
                title: 'MyCompony',
                instructions: 'Log in with username and password.',
                defaults: {
                    required: true,
                    labelAlign: 'left',
                    labelWidth: '40%'
                },
                items: [
                    {
                        xtype: 'textfield',
                        name: 'username',
                        id: 'username',
                        label: 'Name',
                        value: 'user',
                        autoCapitalize: false
                    },
                    {
                        xtype: 'passwordfield',
                        name: 'password',
                        id: 'password',
                        label: 'Password',
                        value: 'test'
                    }
                ]
            },
            {
                xtype: 'toolbar',
                docked: 'bottom',
                items: [
                    {xtype: 'spacer'},
                    {
                        text: 'Reset',
                        handler: function() {
                            var form = this.parent.parent;
                            form.reset();
                        }
                    },
                    {
                        text: 'Login',
                        ui: 'confirm',
                        handler: function() {
                            var form = this.parent.parent;

                            var username = form.getValues().username;//form.down('#username').getValue();
                            var password = form.getValues().password;//down('#password').getValue();
                            form.fireEvent('login', username, password);
                        }
                    }
                ]
            }
        ]
    },

    resetForm: function() {
        var view = this.parent;
        view.down("#username").setValue("");
        view.down("#password").setValue("");
    }
});
app/view/workorder/map.js:

Ext.define('AddressBook.view.workorder.Map', {
    extend: 'Ext.Panel',
    xtype: 'map-show',
    requires: [
        'Ext.Map'
    ],
    config: {
        title: 'Information',
        layout: 'card',
        items: [
            {
                xtype: 'map',
                mapOptions : {
                    zoom : 15,
                    mapTypeId : google.maps.MapTypeId.ROADMAP,
                    navigationControl: true,
                    navigationControlOptions: {
                        style: google.maps.NavigationControlStyle.DEFAULT
                    }
                }
            }
        ]
    },

    centerMap: function(newRecord) {
        if (newRecord) {
            this.down('map').setMapCenter({
                latitude: newRecord.data.latitude,
                longitude: newRecord.data.longitude
            });
        }
    },

    setMarkers: function(markers) {
        var mapPanel = this;
        var map = this.down("map")._map;
        mapPanel.markerDataDict = {};
        mapPanel.markerDict = {};


        if(!mapPanel.infowindow) {
            mapPanel.infowindow = new google.maps.InfoWindow({
                content: 'Sencha HQ'
            });
        }
        for(var i = 0 ;i < markers.length; i++) {
            var markerData = markers[i];
            map.setZoom(15);
            var latitude = Number(markerData.data.latitude);
            var longitude = Number(markerData.data.longitude);
            var position = new google.maps.LatLng(latitude, longitude);
            mapPanel.markerDataDict[position] = markerData;
            var marker = new google.maps.Marker({
                position: position,
                title : markerData.data.id,
                map: map
            });
            mapPanel.markerDict[position] = marker;

            google.maps.event.addListener(marker, 'click', function(mouseEvent) {
                var lat = Math.round(mouseEvent.latLng.lat() * 1000000)/1000000;
                var lng = Math.round(mouseEvent.latLng.lng() * 1000000)/1000000;
                var id = mapPanel.markerDataDict[mouseEvent.latLng].data.id;
                mapPanel.infowindow = new google.maps.InfoWindow();
                mapPanel.infowindow.setContent(['Werkorder: '+ id +'<br/>',
                                                'lat.:' + lat + '<br/>',
                                                'long.:' + lng ].join(""));
                if(mapPanel.oldInfowindow)
                    mapPanel.oldInfowindow.close();
                mapPanel.oldInfowindow = mapPanel.infowindow;
                mapPanel.infowindow.open(map, mapPanel.markerDict[mouseEvent.latLng]);
                mapPanel.infowindow.setPosition(mouseEvent.latLng);
                mapPanel.fireEvent('markerClicked', mapPanel.markerDataDict[mouseEvent.latLng])
            });
        }
    }
});
app/controller/AppController.js:

Ext.define('AddressBook.controller.AppController', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            main: 'mainview',
            editButton: '#editButton',
            contacts: 'contacts',
            loginForm: 'loginForm',
            showMap: 'map-show',
            editContact: 'contact-edit',
            saveButton: '#saveButton'
        },

        control: {
            main: {
                push: 'onMainPush',
                pop: 'onMainPop'
            },
            editButton: {
                tap: 'onContactEdit'
            },
            contacts: {
                itemtap: 'onMarkerSelect'
            },
            loginForm: {
                login: 'onLogin'
            },
            showMap: {
                markerClicked: 'onMarkerSelect'
            },
            saveButton: {
                tap: 'onContactSave'
            },
            editContact: {
                change: 'onContactChange'
            }
        }
    },

    onMainPush: function(view, item) {
        var editButton = this.getEditButton();

        if (item.xtype == "map-show") {
            this.getLoginForm().reset();

            this.showEditButton();
        } else {
            this.hideEditButton();
        }
    },

    onMainPop: function(view, item) {
        if (item.xtype == "contact-edit") {
            this.showEditButton();
        } else {
            this.hideEditButton();
        }
    },

    onMarkerSelect: function(record) {
        var editButton = this.getEditButton();

        if (!this.showEdit) {
            this.showEdit = Ext.create('AddressBook.view.workorder.Edit');
        }

        // Bind the record onto the show contact view
        this.showEdit.setRecord(record);

        // Push the show contact view into the navigation view
        this.getMain().push(this.showEdit);
    },

    onLogin: function(username, password) {
        var controller = this;
        Ext.Ajax.request({
            url: 'login.php',
            method: 'POST',
            disableCaching: true,

            params: {
                username: username,
                password: password
            },

            success: function(response) {
                console.log("Login successful for {username}");
                var editButton = controller.getEditButton();
                if (!controller.showContact) {
                    controller.showContact = Ext.create('AddressBook.view.workorder.Map');
                }

                var store = Ext.getStore("WorkOrders");
                store.load({callback: function(records, operation, success) {
                                if(success) {
                                    console.log(records);
                                    controller.showContact.centerMap(store.data.items[0]);
                                    controller.showContact.setMarkers(store.data.items);
                                    // Push the show contact view into the navigation view
                                    controller.getMain().push(controller.showContact);
                                    controller.getLoginForm().resetForm();
                                }
                            },
                            scope: this
                });

            },

            failure: function(response) {
                console.log("Login failure for {username}");
            }
        });

    },

    onMarkerClicked: function(markerData) {

    },

    onContactEdit: function() {
        if (!this.editContact) {
            this.editContact = Ext.create('AddressBook.view.workorder.Edit');
        }

        // Bind the record onto the edit contact view
        this.editContact.setRecord(this.getShowContact().getRecord());

        this.getMain().push(this.editContact);
    },

    onContactChange: function() {
        this.showSaveButton();
    },

    onContactSave: function() {
        var record = this.getEditContact().saveRecord();

        this.getShowContact().updateRecord(record);

        this.getMain().pop();
    },

    showEditButton: function() {
        var editButton = this.getEditButton();

        if (!editButton.isHidden()) {
            return;
        }

        this.hideSaveButton();

        editButton.show();
    },

    hideEditButton: function() {
        var editButton = this.getEditButton();

        if (editButton.isHidden()) {
            return;
        }

        editButton.hide();
    },

    showSaveButton: function() {
        var saveButton = this.getSaveButton();

        if (!saveButton.isHidden()) {
            return;
        }

        saveButton.show();
    },

    hideSaveButton: function() {
        var saveButton = this.getSaveButton();

        if (saveButton.isHidden()) {
            return;
        }

        saveButton.hide();
    }
});
app/model/WorkOrder.js:

Ext.define('AddressBook.model.WorkOrder', {
    extend: 'Ext.data.Model',

    config: {
        fields: [
            'id',
            'lastName',
            'latitude',
            'longitude'
        ]
    }
});
app/store/WorkOrders.js:

Ext.define('AddressBook.store.WorkOrders', {
    extend: 'Ext.data.Store',

    config: {
        model: 'AddressBook.model.WorkOrder',
        autoLoad: false,
        sorters: 'id',
        proxy: {
            type: 'ajax',
            url: 'werkorders.json',
            reader: {
                type: 'json'
            }
        }
    }
});

是的,我知道这个很棒的视频,并且研究了这个例子。很清楚。但最后我无法将其集成到我的代码中。我的问题仍然是如何将表单与导航选项卡视图组合在单独的视图中。以及如何在控制器中获取[Login]按钮的处理程序,并让该控制器返回其已成功记录的消息,以便视图堆栈可以推送新视图。是的,我知道这段很棒的视频,并研究了该示例。很清楚。但最后我无法将其集成到我的代码中。我的问题仍然是如何将表单与导航选项卡视图组合在单独的视图中。以及如何在控制器中获取[Login]按钮的处理程序,并让该控制器返回其已成功记录的消息,以便视图堆栈可以推送新视图。是的,谢谢,但不是。它没有回答我的问题。顺便说一句,您在这里指出的代码不是my View.js,因为它还包含控制器部件。我知道MVC的优点。这就是为什么我要努力得到答案。在app.js中保留所有逻辑会让我发疯。对我来说,最大的优势是所有数据都存储在一个地方模型上,这让你在整个应用程序中始终保持一致的表示。第二,我想说的是,能够重用代码和消除冗余控制器使它不那么容易出错,第三,它有助于团队工作。是的,谢谢,但它没有回答我的问题。顺便说一句,您在这里指出的代码不是my View.js,因为它还包含控制器部件。我知道MVC的优点。这就是为什么我要努力得到答案。在app.js中保留所有逻辑会让我发疯。对我来说,最大的优势是所有数据都存储在一个地方模型上,这让你在整个应用程序中始终保持一致的表示。第二,我要说的是,能够重用代码和消除冗余控制器使它不那么容易出错,第三,它有助于团队合作。感谢您的工作!这节省了我一些时间。这里有一些你的工作的7z文件。我添加了touch.js和.css文件并对其进行了测试!unix行结尾。windows行结束感谢这项工作!这节省了我一些时间。这里有一些你的工作的7z文件。我添加了touch.js和.css文件并对其进行了测试!unix行结尾。W 印支线末端