extjs - 如何从另一个控制器或闭包正确调用控制器方法

2024-07-04

我是 extjs 的新手,我正在使用 MVC 架构。

当我的应用程序引用控制器的方法时,我会这样做(在MyApp.Application):

Mb.app.getController('Main').myMethod();

虽然已经很长了,但我认为这是可行的方法。

当控制器在闭包中调用它自己的方法时,我被引导使用此代码(在MyApp.controller.Main:

controllerMethodOne: function(){
    Ext.Ajax.request({
        url: ...,
        params: ...,
        success: (function(response){
            list = Ext.JSON.decode(response.responseText);
            list.forEach(function(item){
                storeMenu.add(
                    Ext.create('Ext.menu.Item', {
                        text: item.text,
                        handler: function(el){MyApp.app.getController('Main').controllerMethodTwo()}
                    })
                )
            })
        })
    })
},

我引用了该方法MyApp.app.getController('Main').controllerMethodTwo()因为this没有引用闭包中的控制器对象,因此this..controllerMethodTwo()不工作。

我发现这完全令人费解,我希望有人有一个想法来解决这个问题MyApp.app.getController-解决方法。

Update

感谢所有建议,我可以优化我的代码并提出:

// in my controller
    mixins: ['Mb.controller.mixin.StoreMenu'],
    // I use that style of menus in two controllers thats why I use a mixin
    init: function() {
        this.control({
            '#vg_storeMenu menuitem': {
                click: this.onStoreMenuClicked
            }
        })
    },

// the controller mixin
Ext.define('Mb.controller.mixin.StoreMenu', {
    extend: 'Ext.app.Controller',
    buildStoreMenu: function(store_name){
        var storeMenu = Ext.ComponentQuery.query('#' + store_name + 'Menu')[0];
        Ext.Ajax.request({
            url: Paths.ajax + 'json.php',
            params: {list: store_name + 's'},
            success: (function(response){
            list = Ext.JSON.decode(response.responseText);
            items = Ext.Array.map(list, function(item) {
                return {
                    xtype: 'menuitem',
                    text: item.text
                }
            });
                storeMenu.add(items);
            })
        })
    },
    onStoreMenuClicked: function(el){
        ...
    }
});

实际上,您的代码中至少存在四个明显不同的问题:

  • 类内方法调用的范围处理
  • 组件创建效率低下
  • 控制器中的组件事件处理
  • 控制器间通信

范围处理

第一个问题可以通过使用闭包或将范围参数传递给 Ajax 请求来解决,如上面@kevhender 所描述的。鉴于此,我建议编写更清晰的代码:

controllerMethodOne: function() {
    Ext.Ajax.request({
        url: ...,
        params: ...,
        scope: this,
        success: this.onMethodOneSuccess,
        failure: this.onMethodOneFailure
    });
},

// `this` scope is the controller here
onMethodOneSuccess: function(response) {
    ...
},

// Same scope here, the controller itself
onMethodOneFailure: function(response) {
    ...
}

组件创建

创建菜单项的方式效率较低,因为every菜单项将被创建并一一渲染到 DOM。这也几乎没有必要:您预先拥有项目列表并且您可以控制,因此让我们保持代码的美观和声明性,并一次性创建所有菜单项:

// I'd advocate being a bit defensive here and not trust the input
// Also, I don't see the `list` var declaration in your code,
// do you really want to make it a global?
var list, items;

list  = Ext.JSON.decode(response.responseText);
items = Ext.Array.map(list, function(item) {
    return {
        xtype: 'menuitem',
        text: item.text
    }
});

// Another global? Take a look at the refs section in Controllers doc
storeMenu.add(items);

这里的变化是我们正在迭代list并创建即将出现的菜单项声明的新数组。然后我们一次性添加它们,节省大量重新渲染和重新布局的资源storeMenu.

组件事件处理

当这个函数所做的只是调用控制器时,在每个菜单项上设置一个处理函数是完全没有必要的,而且效率很低。当单击菜单项时,它会触发click事件 - 您所需要做的就是连接控制器以侦听这些事件:

// Suppose that your storeMenu was created like this
storeMenu = new Ext.menu.Menu({
    itemId: 'storeMenu',
    ...
});

// Controller's init() method will provide the wiring
Ext.define('MyController', {
    extend: 'Ext.app.Controller',

    init: function() {
        this.control({
            // This ComponentQuery selector will match menu items
            // that descend (belong) to a component with itemId 'storeMenu'
            '#storeMenu menuitem': {
                click: this.controllerMethodTwo
            }
        });
    },

    // The scope is automatically set to the controller itself
    controllerMethodTwo: function(item) {
        ...
    }
});

一种最佳实践是尽可能细粒度地编写 ComponentQuery 选择器,因为它们是全局的,如果您不够精确,您的控制器方法可能会捕获来自不需要的组件的事件。

控制器间通信

目前这可能有点牵强,但既然您使用的是 Ext JS 4.2,您不妨利用我们在这方面添加的改进。在 4.2 之前,有一种首选(也是唯一)的方法从另一个控制器调用一个控制器的方法:

Ext.define('My.controller.Foo', {
    extend: 'Ext.app.Controller',

    methodFoo: function() {
        // Need to call controller Bar here, what do we do?
        this.getController('Bar').methodBar();
    }
});

Ext.define('My.controller.Bar', {
    extend: 'Ext.app.Controller',

    methodBar: function() {
        // This method is called directly by Foo
    }
});

在 Ext JS 4.2 中,我们添加了事件域的概念。这意味着现在控制器不仅可以监听组件的事件,还可以监听其他实体的事件。包括自己的控制器域:

Ext.define('My.controller.Foo', {
    extend: 'Ext.app.Controller',

    methodFoo: function() {
        // Effectively the same thing as above,
        // but no direct method calling now
        this.fireEvent('controllerBarMethodBar');
    }
});

Ext.define('My.controller.Bar', {
    extend: 'Ext.app.Controller',

    // Need some wiring
    init: function() {
        this.listen({
            controller: {
                '*': {
                    controllerBarMethodBar: this.methodBar
                }
            }
        });
    },

    methodBar: function() {
        // This method is called *indirectly*
    }
});

这可能看起来是一种更复杂的做事方式,但实际上在大型应用程序中使用它要简单得多,并且它解决了我们遇到的主要问题:控制器之间不再需要硬绑定,您可以单独测试每个控制器。

请参阅我的博客文章中的更多内容:Ext JS 4.2 中的控制器事件 http://nohuhu.org/development/controller-events-in-ext-js-4-2/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

extjs - 如何从另一个控制器或闭包正确调用控制器方法 的相关文章

  • 在闭包上下文中 for 循环内声明的 let 变量的行为

    在下面的代码片段中 函数传递给setTimeout与变量形成闭包i这是存在于script范围 所以该函数包含一个参考到变量i 的价值i之前更新为5i已记录到控制台 输出是 5 5 5 5 5 带换行符 script js let i for
  • 在显示选项卡栏控制器之前启动登录视图

    我有一个使用故事板开发的 ios5 应用程序 当前在初始启动时显示选项卡栏控制器视图 我想在显示选项卡栏控制器之前显示登录屏幕 用户输入用户名和密码 系统将验证用户身份 如果成功 则显示选项卡栏控制器 我尝试了以下 3 个选项 但没有成功
  • ExtJS4 中的自动高度问题

    我们在 ExtJS3 中使用 autoHeight 来创建窗口 但现在在 ExtJS4 中它不起作用 除了这个还有其他选择吗 如果是 请告诉我 Read this http www sencha com forum showthread p
  • 如何在 extjs 4 中设置面板/窗口透明?

    如何将面板或窗口设置为透明 半透明 通过CSS还是设置html代码 extjs版本是4 0 7 谢谢 您可以使用 CSS 来完成此操作 将此配置添加到您的面板中 bodyStyle background transparent or bod
  • Javascript 循环内的事件处理程序 - 需要闭包吗?

    我正在使用一些我从别人那里接管的 html 和 Javascript 代码 该页面每十秒重新加载一个数据表 通过异步请求 然后使用一些 DOM 代码重新构建该表 有问题的代码看起来像这样 var blah xmlres getElement
  • 闭包作为数据合并习惯的解决方案

    我正在尝试解决闭包问题 而且我think我发现了一个案例 他们可能会有所帮助 我有以下几部分需要处理 一组正则表达式 旨在清理状态名称 位于函数中 具有州名称 上述函数创建的标准化形式 和州 ID 代码的 data frame 用于链接两者
  • 在 Ajax 类型的 Extjs 5 存储上进行本地分页

    我正在开发一个应用程序 从一开始就加载所有数据并不是很不方便 我通过 Ajax 从服务器获取 json 数据 而我的商店执行此操作非常简单 Ext define MODIFE store CentroBeneficio extend Ext
  • 循环内的 JavaScript 闭包 – 简单的实际示例

    var funcs let s create 3 functions for var i 0 i lt 3 i and store them in funcs funcs i function each should log its val
  • 嵌套函数中的局部变量

    好吧 请耐心听我说 我知道这看起来会非常复杂 但请帮助我理解发生了什么 from functools import partial class Cage object def init self animal self animal ani
  • Groovy:在调用任何方法之前和之后透明地执行代码

    假设我们有一个带有一些方法 静态或非静态 的常规类 我想要做的是在调用此类的每个方法之前和之后执行一些代码 而无需触摸该类 也无需动态操作每个方法内部的代码 我尝试使用 groovy 元类 获取元类的所有方法 然后用包装方法动态替换每个方法
  • 如何扩展 Shopware 6 控制器操作

    我正在为 Shopware 6 构建一个插件 但似乎找不到任何有关如何扩展现有控制器操作的文档 我找到了这个如何向 Shopware 中的帐户控制器添加操作 https stackoverflow com questions 4634008
  • 将 JSON 数据传递到 Spring MVC 控制器

    我需要将 JSON 字符串发送到 Spring MVC 控制器 但我没有 有任何表单绑定 我只需要将纯 JSON 数据发送到 Controller 类 我正在对 Controller 方法进行 jQuery AJAX 调用 如下面的代码所示
  • AngularJS:从控制器内读取路由参数

    如何在 AngularJS 控制器中读取 URL 中的参数 假设我有一个像这样的网址http localhost var value我希望将该值存储在控制器内的变量中 var value URL 我尝试过使用 routeParams val
  • 重载控制器动作

    几分钟前 当我尝试在我的一个控制器中重载操作时 我有点惊讶 I had public ActionResult Get return PartialView return all things I added public ActionRe
  • 在控制器中调用模型方法

    我在这里遇到了一些困难 我无法成功调用属于ProjectPage model in the ProjectPage 控制器 我在我的ProjectPage控制器 def index searches Project published fi
  • Ext JS grid 获取最后选定行的 dom

    有没有机会获得DOM网格内最后选定行的值 我只能得到带有值的记录 而不是DOM元素 和DOM元素我的意思是 tr 所选行的元素 var selectedRecord grid getSelectionModel getLastSelecte
  • up() 和 down() 与 Ext.getCmp()

    我很困惑我需要在 up down 和 Ext getCmp ID 之间使用哪一个作为 grep 对象 对我来说 定义对象的 ID 并通过 Ext getCmp ID 检索对象更容易 而且代码看起来更干净 例如 console log thi
  • 我希望根据当前路线将多个变量切换为 true 或 false

    我希望根据当前路由将多个变量切换为 true 或 false 控制器在页面加载时检查该路由 VpcYeoman SuperTableController Ember ArrayController extend routedToLocati
  • 如何防止 extjs 网格在点击单元格时滚动?

    我目前正在使用基于可编辑网格示例的 Extjs 4 网格组件 我希望有一个与每个单元格关联的链接 这样当我单击一个单元格时 它会将我带到另一个页面 但是 当单击链接时页面上会触发垂直滚动 例如尝试减小尺寸http dev sencha co
  • 带参数的 Rails link_to 远程

    我想使用链接触发模型的远程操作 基本上 这个链接所需要做的就是触发一个带有一个参数的方法 这是我的代码 link to Move Up reorder collection folder path collection folder reo

随机推荐

  • 用于结构化数据格式(XML、JSON)内的目标内容的标准表示法?

    问题是这样的 我处于 Web 环境中 并且拥有以某种结构化格式 例如 XML 或 JSON 表示的数据 我想定位这些表示内的元素 这是一个例子 动物园的 XML 表示形式
  • 避免 xjc 生成的代码出现编译器警告

    我的根本问题是如何从 未经检查的泛型类型 Eclipse 编译器警告中受益 但问题视图中没有这些警告列表 这些警告被 xjc 从 xsd 文件生成的 java 类的噪声污染 通过 maven jaxb2 插入 我读过其他地方 我可以忽略每个
  • 将字符串中的每个字符转换为 ASCII

    谁能告诉我如何轻松地将字符串中的每个字符转换为 ASCII 值 以便我可以对这些值求和 我需要对哈希函数的值求和 字符串中的每个字符都已经是 ascii include
  • GlassFish 服务器日志的位置

    我在 Windows 7 64 位计算机上安装了 NetBeans IDE 显然 NetBeans 附带了 GlassFish 服务器 我目前在一个项目中遇到问题 想检查服务器日志 请问这些保存在哪里 一般来说 日志位于 YOUR GLAS
  • /lib64/libc.so.6:找不到版本“GLIBC_2.14”。为什么我会收到此错误?

    我在 Node js 中工作 我已经安装了鹰嘴豆泥包 它安装正确 我正在使用这个包来修改 pdf 文件 下载 pdf 时 我调用鹰嘴豆泥 单击下载时出现此错误 Error lib64 libc so 6 version GLIBC 2 14
  • 部署到 10.6 时出现 ARC 错误

    我的应用程序在 10 7 上运行和测试 但后来意识到我也需要它在早期版本上运行 不幸的是 我从一开始就在 ARC 的情况下开始了这个项目 现在我的构建设置是调试基础 sdk 10 7 并发布基础 sdk 10 6 当我尝试存档我的应 用程序
  • Laravel 4 中的图标链接

    有人可以帮忙重写这个 从 HTML 到 Laravel4 吗 a href index php span i class icon home i span Home a 该页面的路由名称只是 我知道如何在 Laravel 中编写简单的链接
  • 为什么 List.contains() 在 Collections Java 中将 Object 作为参数 [重复]

    这个问题在这里已经有答案了 The java util List contains Object o 方法需要Object作为参数并在内部使用Object equals Object o 如上所述here http docs oracle
  • 查找 R 中已知中心点的半径范围内的纬度/经度

    我有一个具有已知纬度和经度的已知点 中心 并且我在 df 中有一些坐标 以纬度 经度为单位 我想查看哪些坐标在距中心点 5 公里或更小的半径内 Centre mylon lt c 2 106472 mylat lt c 57 14455 坐
  • 调整图像大小以适合父节点

    如何让 ImageView 中的图像自动调整大小以使其始终适合父节点 这是一个小代码示例 Override public void start Stage stage throws Exception BorderPane pane new
  • 覆盖引导样式不起作用

    我有这种简单的情况 我有一种没有定义的风格display属性值 我最近在我的项目中添加了 bootstrap 没有出现重大问题 只有一个 In label bootstrap style is defined a display inlin
  • Angular Service Worker 在不支持的浏览器上

    Angular 团队做得非常出色 并在版本 5 中引入了 Service Worker 支持 文档 https angular io guide service worker intro非常有帮助 在阅读相关文章后我真的可以看到这些事情是如
  • Numpy“shape”函数返回 2D 数组的 1D 值

    所以我创建了这个数组作为示例 a np array 1 1 1 1 2 2 2 2 3 3 3 3 4 13 49 13 49 10 10 2 2 11 1 1 1 2 22 2 2 3 33 3 3 4 133 49 13 49 100
  • 如何读取PHP上传的文件头?

    我们能否在PHP中读取文件的头信息来判断上传的文件类型 我不想依赖 FILES control name from client type 我们知道 该属性通过读取上传文件的扩展名来确定文件类型 如果用户重命名怎么办 test jpg gt
  • 了解张量流间/内并行线程

    我想更多地了解这两个参数 操作内和操作间并行线程 session conf tf ConfigProto intra op parallelism threads 1 inter op parallelism threads 1 我读过这篇
  • PHP 使用正则表达式分解字符串

    我有一个长字符串 由一系列用单引号分隔的句子组成 Example This s sentence number 1 This s sentence number 2 请注意 该字符串的句子本身有单引号部分 这些部分已被转义 我需要使用单引号
  • 在网页上使用网络摄像头进行视频录制[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我需要在我的网页上通过网络摄像头录制视频 有哪些可用的插件 我的网站是使用Ruby on Rails框架开发的 问候 潘卡伊 如果 HTML5 解决方
  • 如何:覆盖依赖属性的元数据

    如何覆盖默认依赖属性元数据 例如 文本框的 Text 属性 我用这个代码 class UCTextBox TextBox public UCTextBox var defaultMetadata TextBox TextProperty G
  • 无法登录 SQL Server + SQL Server 身份验证 + 错误:18456

    我已经在 localhost sql2008 服务器上创建了登录帐户 例如 User123 映射到数据库 默认 SQL Server 上的身份验证模式设置为两者 Windows 和 SQL 但登录 SQL Server 失败并显示以下消息
  • extjs - 如何从另一个控制器或闭包正确调用控制器方法

    我是 extjs 的新手 我正在使用 MVC 架构 当我的应用程序引用控制器的方法时 我会这样做 在MyApp Application Mb app getController Main myMethod 虽然已经很长了 但我认为这是可行的