`
rensanning
  • 浏览: 3538014 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:37949
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:606418
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:681051
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:88661
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401196
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69540
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91396
社区版块
存档分类
最新评论

Titanium通过回调和事件来降低耦合度

阅读更多
【官方地址】https://wiki.appcelerator.org/display/guides/Callbacks+and+Events+for+Loose+Coupling

我们在阅读了Appcelerator wiki中的“JavaScript最佳实践”之后都应该知道,使用全局变量或者破坏全局命名空间是编写高质量,可维护代码的禁忌。然而我们也知道旧的习惯是很难改的,我们在写代码时需要“this”来设值?只能创建一个全局变量来使用了。

通过这种方法解决问题最终他还会为我们带来麻烦。我们暂时忘记全局变量,将会有另外一种方法来得到同样的信息。

这里需要我们写在黄色便签上,让我们重视的有三点:
1、我们将要编写的是模块化代码(至少从现在开始)
2、基于事件的编程是很好的
3、只有在不得已的时候再使用全局变量

获取地理信息
这里,首先问题是什么?获取用户的当前地理位置信息。

这个处理会被异步执行,我们要更新的UI控件在另外一个文件中,当然,这是一个模块话的代码。

我们都知道通过调用API Titanium.Geolocation.getCurrentPosition使用回调函数来让我们知道什么时候它找到了地理位置信息。
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = .25;
Ti.Geolocation.purpose = "Callbacks Are Your Friend";

// 调用API
Ti.Geolocation.getCurrentPosition(function(e) {
  
  // 当获取位置信息出错时
  if (e.error) {
    Ti.API.error('geo - current position' + e.error);
    return;
  }

  // 获取地理位置信息
  Ti.App.info('got a location ',JSON.stringify(e));
});


把地理位置信息放在有用的地方
这里我们可以在回调函数的外边创建一个全局变量,来使用它获取信息。
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = .25;
Ti.Geolocation.purpose = "Callbacks Are Your Friend";

// 在回调中保存的坐标信息(全局)
var global_var_coords;

// 调用API
Ti.Geolocation.getCurrentPosition(function(e) {
  
  // 当获取位置信息出错时
  if (e.error) {
    Ti.API.error('geo - current position' + e.error);
    return;
  }

  // 获取地理位置信息
  Ti.App.info('got a location ',JSON.stringify(e));

  // 给全局变量赋值
  global_var_coords = e.coords
});


但是这仅仅是帮助了我们,如果需要更新的UI控件跟回调处于同一个JS文件的情况。这不足以是我们写出模块化的代码。我们绝不能将UI代码和获取地理位置信息的逻辑代码混淆在一起。

通过事件监听把地理位置信息放在更好的地方
那么我们下来该做什么?首先是要摆脱全局变量,激发一个事件来指示地理位置信息已经成功被取到。
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = .25;
Ti.Geolocation.purpose = "Callbacks Are Your Friend";

// 全局监听
Ti.App.addEventListener('location.updated',function(coords){
   Ti.API.debug(JSON.stringify(coords));
}

// 调用API
Ti.Geolocation.getCurrentPosition(function(e) {
  
  // 当获取位置信息出错时
  if (e.error) {
    Ti.API.error('geo - current position' + e.error);
    return;
  }

  // 获取地理位置信息
  Ti.App.info('got a location ',JSON.stringify(e));

  // 激发含有地理位置信息的事件
  Ti.App.fireEvent('location.updated',e.coords);

});


这样,在应用的任何我们需要获取地理位置信息的地方,我们都可以创建一个监听来获得坐标信息。这样很棒,不再需要全局变量了!

也有另外一种方法:在回调中使用回调
我们在设备获取地理位置信息完成后调用一个函数。和激发一个事件一样,我们将调用一个函数,把我们从设备上获取到的地理位置信息坐标作为参数传给它。
//
// file_with_location.js
//
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = .25;
Ti.Geolocation.purpose = "Callbacks Are Your Friend";
/**
* @param {Object} _callback 地理位置信息查询完成后调用                      
*/
function currentLocation(_callback) {

    // 调用API
    Ti.Geolocation.getCurrentPosition(function(e) {
  
        // 当获取位置信息出错时
        if (e.error) {
            Ti.API.error('geo - current position' + e.error);

            // to keep it simple, just returning null, could be
            // error information
            if (_callback) {
                _callback(null);
            } 
            return;
        }

        // 获取地理位置信息
        Ti.App.info('got a location ',JSON.stringify(e));

        // 激发含有地理位置信息的事件
        Ti.App.fireEvent('location.updated',e.coords);
        
        // 用坐标调用回调函数
        if (_callback) {
            _callback(e.coords);
        } 

    });
}


在我们代码的其他地方,我们需要获得信息后把信息更新到UI控件上。
Ti.include('file_with_location.js');

// 打开一个窗口
var window = Ti.UI.createWindow({
  backgroundColor:'white'
});

var coordsLbl = Titanium.UI.createLabel({
   text:"NO LOCATION",
   left: 10,
   width: 240,
   height: 'auto',
   top: 20,
   textAlign: 'left',
});

window.add(coordsLbl);
window.open();
    
// 执行回调获取地理位置信息, gpsCallback方法被传入获取地理位置信息的方法
// 他将在获取到地理位置信息伙子出错的时候被调用
currentLocation(gpsCallback);


/**
 * @param {Object} _coords 地理位置信息的经纬度值
 */
function gpsCallback(_coords) {
    if (_coords) {
       coordsLbl.text = String.format("lon: %s\n lat: %s ", _coords.longitude + "", _coords.latitude + "");
    } else {
       coordsLbl.text = "NO LOCATION";
    }
}


Kevi说模块化是最好的
Kevin Whinnery: Write Better JavaScript: video| slides

好,我们现在已经在包含文件中有了GPS代码,它和UI代码分离,我们可以在任何需要获取地理位置信息的地方调用它,或者是一个事件,或者是一个回调函数。但是,我们还是没有做到-模块化CommonJS,还有“requires”的一切。

我们想做一个好的Appcelerator市民,编写出比Kitchen-sink更强大的代码。KitchenSink 毕竟只是一个演示API功能的,它并不是最好的例子。

这里让我们把我们的地理位置信息文件转化成一个模块。只需要在函数名之前加一个“exports”,并保证其公有。

//
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
Titanium.Geolocation.distanceFilter = .25;
Ti.Geolocation.purpose = "Callbacks Are Your Friend";

// PUBLIC FUNCTION
/**
* @param {Object} _callback 地理位置信息查询完成后调用                       
*/
exports.currentLocation = function(_callback) {
    Titanium.Geolocation.getCurrentPosition(function(e) {

        if(e.error) {
            alert('error ' + JSON.stringify(e.error));

            // 为了保持一致,返回null
            if(_callback) {
                _callback(null);
            }
            return;
        }

        Ti.App.fireEvent('location.updated', e.coords);

        if(_callback) {
            _callback(e.coords);
        }
    });
};


在我们的ui.js文件的创建窗口的位置,我们需要加载这个含有地理位置信息取得的模块。完整的例子,我们把文件命名为“maps.js”。我们需要添加一下语句:
引用
require

记住:在使用requie时不需要包含".js"扩展名,他不需要。
var maps = require('lib/maps');


当你调用方法时:
// do the callback to get current location
maps.currentLocation(gpsCallback);


这里是完整的ui.js:
// private vars
var mainWindow, callback_label_coords;
var styles = require('styles');
var maps = require('lib/maps');

/**
 * @param {Object} args  properties for the window
 */
exports.AppWindow = function(args) {
    var instance, event_label, callback_label;

    // create window
    instance = Ti.UI.createWindow(args);

    // make callback label
    callback_label = Ti.UI.createLabel(styles.callback_label);
    instance.add(callback_label);
    callback_label_coords = Ti.UI.createLabel(styles.coords_label);
    instance.add(callback_label_coords);

    // make event listener label
    event_label = Ti.UI.createLabel(styles.event_label);
    instance.add(event_label);
    event_label_coords = Ti.UI.createLabel(styles.coords_label);
    instance.add(event_label_coords);

    // create event Listener
    Ti.App.addEventListener('location.updated', function(_coords) {
        event_label_coords.text = String.format("longitude: %s\n latitude: %s ", _coords.longitude + "", _coords.latitude + "");
    });
    // do the callback to get current location
    maps.currentLocation(gpsCallback);
    
    // save the window
    mainWindow = instance;
    return instance;
};
/**
 * @param {Object} _coords lat, lon values from locationo
 */
function gpsCallback(_coords) {
    callback_label_coords.text = String.format("longitude: %s\n latitude: %s ", _coords.longitude + "", _coords.latitude + "");
}


总结
使用回调和事件对你的代码是有益的。它减少耦合,更好的分离业务逻辑和表现层。从现在开始,我们将在应用开发中更加强化模块化代码,这将放映在不久以后我们带给你所有的内容之中。
Keep coding strong!

代码
CallbacksAreYourFriend on Github
分享到:
评论

相关推荐

    Titanium中支持IOS设备的拖拽

    5. **处理拖放事件**:根据业务需求,编写JavaScript回调函数来响应拖放事件,例如拖放开始、拖动中、拖放到目标上、拖放离开和拖放结束。这些回调将处理数据交换、更新界面状态等操作。 6. **兼容性检查**:由于...

    titanium 打开本地网络

    例如,下面的代码会监听`change`事件,每当网络状态改变时,都会触发回调函数: ```javascript Ti.Network.addEventListener('change', function(event) { var networkStatus = event.online; if (networkStatus)...

    Titanium中文版开发手册

    样式和主题使得开发者可以通过简单的CSS样例来定义和管理应用的视觉样式。这部分涵盖了如何创建自定义样式、使用全局主题以及如何将样式应用于不同视图。 6. **Alloy Views(Alloy视图)** 视图是用户界面的构建...

    TitaniumBackup_6.0.5.1

    TitaniumBackup_6.0.5.1,这款专业版应用,以其强大的功能和高效的操作,为用户提供了可靠的数据管理工具。它的静默恢复特性,更是为用户带来了前所未有的便利。 Titanium Backup 是一款备受赞誉的第三方备份工具,...

    Titanium使用JavaScript来开发原生iOSAndroid和Windows应用

    虽然JavaScript是解释型语言,但Titanium通过Just-In-Time (JIT) 编译和 Ahead-Of-Time (AOT) 编译策略来提升应用性能。此外,钛合金的组件优化和事件处理机制也有助于减少性能瓶颈。 ### 社区与生态系统 Titanium...

    TiInspector, 通过 Chrome DevTools调试 Titanium Mobile 应用程序.zip

    TiInspector, 通过 Chrome DevTools调试 Titanium Mobile 应用程序 #Ti 检查器Ti检查器允许在 Chrome DevTools web界面中调试 ...工具通过将命令和消息转换为 Chrome 调试协议和 Titanium 调试器协议( 反之亦然)

    Titanium Mobile API

    ### Titanium Mobile API 知识点详解 #### 一、Titanium Mobile API 概述 Titanium Mobile API 是一款由 Appcelerator ...对于希望快速构建高质量移动应用的开发者来说,Titanium Mobile API 是一个值得考虑的选择。

    使用Titanium来开发“Path”的一些创新UI布局 - 左右菜单

    总的来说,通过 Titanium 开发类似 Path 的左右菜单UI,需要掌握 Titanium 的基本语法、Alloy MVC 架构以及手势识别和动画技术。这样的实践可以帮助开发者提高跨平台开发的能力,同时理解如何在有限的移动设备屏幕上...

    Titanium plugin开发初探

    在移动应用开发领域,Titanium 是一个流行的选择,它允许开发者使用 JavaScript 来构建原生的 iOS 和 Android 应用。Titanium 的核心理念是通过跨平台的 JavaScript API 提供与原生功能的无缝对接,而插件开发则是这...

    TITANIUM智能手机应用开发教程

    通过本书《AppceleratorTitanium Smartphone App Development Cookbook》,读者不仅能够学习到TITANIUM的基本操作,还能深入了解如何利用各种高级特性来优化应用性能和用户体验。无论是初学者还是有经验的开发者,都...

    titanium_sdk:这是的Titanium SDK

    会话和事件回调 禁用跟踪 离线模式 事件缓冲 GDPR被遗忘的权利 禁用第三方共享 SDK签名 后台跟踪 设备ID iOS广告识别码 Google Play服务广告标识符 亚马逊广告标识符 调整设备标识符 用户归因 推送令牌 预先安装的...

    Titanium_ziliao

    总结来说,"Titanium_ziliao"项目深入研究了钛合金这一高性能材料在各个领域的应用,包括但不限于航空航天、医疗和体育用品。通过学习这个项目,我们可以了解到钛合金的独特优势,以及它如何在实际项目中发挥重要...

    Titanium资料

    通过这个文档,你可以了解到如何创建、布局和交互各种 UI 元素,如按钮、文本框、图片视图等,以及如何添加事件监听器来响应用户的操作。 接着,`API_TitaniumModule.pdf` 介绍的是 Titanium 模块。模块是 Titanium...

    Titanium开发者平台介绍

    该平台不仅支持移动设备(如Android和iOS),还覆盖了桌面应用开发(Windows、macOS、Linux),这极大地降低了开发者学习成本,提高了开发效率。 #### 二、关键特性 - **开源许可证**:Titanium遵循Apache 2.0开源...

    前端开源库-node-titanium-sdk

    7. **测试套件**:为了确保代码的质量和稳定性,可能会包含单元测试和集成测试的代码,开发者可以通过运行这些测试来验证其修改是否正确。 8. **许可证文件**:开源库通常会包含一份许可证文件,说明软件的使用、...

    Titanium Backup_3.7.4捐赠完全版

    Titanium Backup_3.7.4捐赠完全版

    [Titanium] Appcelerator Titanium 移动应用开发教程 (英文版)

    [Packt Publishing] Appcelerator Titanium 移动应用开发教程 (英文版) [Packt Publishing] Creating Mobile Apps with Appcelerator Titanium (E-Book) ☆ 图书概要:☆ Develop fully-featured mobile ...

    Titanium学习教程

    - **性能接近原生应用**:尽管是通过Web技术编写的应用程序,但Titanium通过底层的编译器和引擎将这些代码转换为高效的原生代码,使得最终产品的性能接近于完全用原生语言(如Objective-C或Java)编写的程序。...

    ecm.titanium-26100.rar

    总的来说,"ecm.titanium-26100.rar"中的工具为汽车爱好者和专业技师提供了一种高效且强大的ECU管理手段,无论是为了提高车辆性能,还是进行故障排查,都能发挥重要作用。但使用前务必确保了解相关法规,并遵循正确...

Global site tag (gtag.js) - Google Analytics