大前端 - TOMMYHU - 专注互联网开发及运营技术,提供相关资料及软件下载,奇趣网络时事评论!
Pages: 9/43 First page Previous page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Next page Final page [ View by Articles | List ]
Oct 11
理解AngularJS中的依赖注入
AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在。在本文中我们将会解释AngularJS依赖注入系统是如何运行的。

Provider服务($provide)
$provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务(service)。服务会被叫做provider的东西来定义,你可以使用$provide来创建一个provider。你需要使用$provide中的provider方法来定义一个provider,同时你也可以通过要求改服务被注入到一个应用的config函数中来获得$provide服务。下面是一个例子:

代码laycode - v1.1
在上面的例子中我们为一个服务定义了一个叫做greeting的新provider;我么可以把一个叫做greeting的变量注入到任何可注入的函数中(例如控制器,在后面会讲到)然后Angular就会调用这个provider的$get函数来返回这个服务的一个实例。在上面的例子中,被注入的是一个函数,它接受一个叫做name的参数并且根据这个参数alert一条信息。我们可以像下面这样使用它:

代码laycode - v1.1
现在有趣的事情来了。factory,service以及value全部都是用来定义一个providr的简写,它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。例如,你可以用下面的代码定义一个和前面完全相同的provider:

代码laycode - v1.1
这非常的重要,所以一定要记住:在幕后,AngularJS实际上是在调用前面出现的代码(就是$provide.provider的版本)。从字面上来说,这两种方法基本上没有差别。value方法也一样 – 如果我们需要从$get函数(也就是我们的factory函数)返回的值永远相同的话,我们可以使用value方法来编写更少的代码。例如如果我们的greeting服务总是返回相同的函数,我们可以使用value来进行定义:

代码laycode - v1.1
再一次申明,以上两种方式的效果完全一样 – 只不过是代码的量不同而已。

现在你可能已经注意到了我们使用的烦人的

代码laycode - v1.1
代码了。由于定义一个新的provider是如此的常用,AngularJS在模块对象上直接暴露了provider方法,以此来减少代码的输入量:

代码laycode - v1.1
上面的代码和前面app.config(...)这样?嗦的写法完全相同。

除了上面提到的可以注入的东西之外,还有一个constant方法。基本上,它和value的用法一致。我们会在后面来讨论两者的不同点。

为了巩固前面的学习成果,下面所有的代码所做的都是同一件事情:

代码laycode - v1.1
注入器($injector)
注入器负责从我们通过$provide创建的服务中创建注入的实例。只要你编写了一个带有可注入性的参数,你都能看到注入器是如何运行的。每一个AngularJS应用都有唯一一个$injector,当应用启动的时候它被创造出来,你可以通过将$injector注入到任何可注入函数中来得到它($injector知道如何注入它自己!)。

一旦你拥有了$injector,你可以动过调用get函数来获得任何一个已经被定义过的服务的实例。例如:

代码laycode - v1.1
注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的invoke方法:

代码laycode - v1.1
如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个provider中返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。

因此,你可以通过调用$injector.invike将服务注入到任何函数中也是合情合理的了。包括:

控制器定义函数
指令定义函数
过滤器定义函数
provider中的$get方法(也就是factory函数)
由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。

配置provider
你可能会感到困惑:既然factorry和value能够节省那么多的代码,为什么还有人要使用provider。答案是provider允许我们进行一些配置。在前面我们已经提到过当你通过provider(或者其他简写方法)创建一个服务时,你实际上创建了一个新的provider,它将定义你的服务如何被创建。我们没有提到的是,这些provider可以被注入到config函数中,你可以和它们进行一些交互。

首先,AngularJS分两个阶段运行你的应用 – config阶段和run阶段。config阶段是你设置任何的provider的阶段。它也是你设置任何的指令,控制器,过滤器以及其它东西的阶段。在run阶段,AngularJS会编译你的DOM并启动你的应用。

你可以在myMod.config和myMod.run中添加任何代码 – 这两个函数分别在两个阶段运行。正如我们看到的,这些函数都是可以被注入的 – 我们在第一个例子中注入了内建的$provide函数。然而,值得注意的是在config阶段,只有provider能被注入(只有两个例外是$provide和$injector)。

例如,下面的代码就是错误的写法:

代码laycode - v1.1
有一个例外:constant,由于它们不能被改变,因此它不能被注入到config中(这就是它和value之间的不同之处)。它们只能通过名字被获取。

无论何时你为一个服务定义了一个provider,这个provider的名字都是serviceProvider。在这里service是服务的名字。现在我们可以使用provider的力量来做一些更复杂的事情了!

代码laycode - v1.1
现在我们在provider中拥有了一个叫做setText的函数,我们可以使用它来自定义我们alert的内容;我们可以再config中访问这个provider,调用setText方法并自定义我们的service。当我们最终运行我们的应用时,我们可以获取greeting服务,然后你会看到我们自定义的行为起作用了。

控制器($controller)
控制器函数是可以被注入的,但是控制器本身是不能被注入到任何东西里面去的。这是因为控制器不是通过provider创建的。然而,有一个内建的AngularJS服务叫做1$controller,它负责设置你的控制器。当你调用myMod.controller(…)时,你实际上是访问了这个服务的provider,就像上面的例子一样。

例如,当你像下面一样定义了一个控制器时:

代码laycode - v1.1
你实际上做的是下面这件事:

代码laycode - v1.1
当Angular需要创建一个你的控制的实例时,它会使用$controller服务(它反过来会使用$injector来调用你的控制器以便它能够被注入依赖项)。

过滤器和指令
filter和directive和controller的运行方式相同;filter会使用一个叫做$filter的服务以及它的provider $filterProvider,而directive使用一个叫做$compile的服务以及它的provider $compileProvidr。下面是相应的文档:

其中,myMod.filter和myMod.directive分别是这些服务的简写。

总结
总结一下,任何能够被$injector.invoke调用的函数都是能被注入的。包括,但不限于下面的这些:

控制器
指令
factory
过滤器
provider中的$get函数
provider函数
服务
provider创建的新服务都可以用来注入。包括:

constant
factory
provider
service
value
另外,内建的服务$controller和$filter也可以被注入,同时你也可以使用这些服务来获得新的过滤器和控制器。

本文译自Understanding Dependency Injection,原文地址https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection
Aug 23

Flux 不指定

tommyhu , 14:54 , 大前端 , Comments(0) , Trackbacks(0) , Reads(1030) , Via Original
Flux应用架构 http://reactjs.cn/react/docs/flux-overview.html

React+Redux
Vue+Vues
Tags:
Aug 19
解决了一个低端设备问题,原来一个页面时间使用了touch和click,而使用了e.preventDefault();不见效果,改为click后就可以了

一.click与300ms延迟

移动浏览器提供一个特殊的功能:双击(double tap)放大

300ms的延迟就来自这里,用户碰触页面之后,需要等待一段时间来判断是不是双击(double tap)动作,而不是立即响应单击(click),等待的这段时间大约是300ms。之前有过简单介绍: 黯羽轻扬:HTML5触摸事件

移动事件提供了 touchstart 、 touchmove 、 touchend 却没有提供tap支持,主流框架(库)都是手动实现了自定义tap事件,以求消除300ms延迟,提高页面响应速度。对于简单的页面,可以把 touchstart 或者 touchend 当作tap来用,但存在一些问题,比如手指接触目标元素,按住不放,慢慢移出响应区域,会触发 touchstart 事件执行对应的事件处理器(本不应该触发), touchend 事件也存在类似的问题。

此外, 使用原生touch事件也存在点击穿透的问题 ,因为click是在touch系列事件发生后大约300ms才触发的,混用touch和click肯定会导致点透问题,下面详细介绍
Aug 17
开始尝试用Ionic做些DEMO,基于angularjs提供数据双向绑定,提供了预制的css class界面样式(类似bootstracp)和angularjs的指令集,例如以下代码ion-header-bar为Ionic基于angularjs开发的内置指令,class="bar-positive"为css class,提供界面ui


当然,Ionic要做的是让前端的人也能玩Android和IOS的应用(就象nodejs一样,es6,es7让js也纯爷们起来,),并且无限趋近于原生,当然如果你玩的安卓开发和swif和溜也没必要搞这个了,毕竟native的体验终归是最好的

window下Ionic开发环境搭建,环境变量修改后已经打开cmd窗口需要重启,


1、下载JDK并配置Java运行环境
     http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
     安装后需要进行如下配置:
     在“系统变量”中,设置3项属性,JAVA_HOME,PATH,CLASSPATH(大小写无所谓),若已存在则点击“编辑”,不存在则点击“新建”。

     1)JAVA_HOME
         C:\Program Files\Java\jdk1.8.0_45

         注意:JAVA_HOME指明JDK安装路径,就是刚才安装时所选择的路径,此路径下包括lib,bin,jre等文件夹。
Highslide JS
        

       2)Path
           %JAVA_HOME%\bin;
    在系统变量Path的值的最前面加入.否则可能在运行时,系统选择部署在前面的jre环境。
    注意:Path使得系统可以在任何路径下识别java命令
Highslide JS
          

       3)CLASSPATH
           .;%JAVA_HOME%\lib
          注意: 点好表示当前目录,不能省略
                 CLASSPATH为java加载类(class or lib)路径,只有类在classpath中,java命令才能识别
Highslide JS
          

         测试:“开始”->“运行”,键入“cmd”,键入命令“java -version”,出现下图画面,说明环境变量配置成功。
Highslide JS
        


2、下载Apache Ant 并将其bin目录路径添加进Path路径
      http://mirror.tcpdiag.net/apache/ant/binaries/
      下载完成后解压 ,如存放在C盘 Program Files目录下则Path中添加如下值 C:\Program Files\apache-ant-1.9.4\bin;
      并添加path环境变量(添加方法和java配置path变量是一样的,注意以 ; 隔开每个环境变量的值)
Highslide JS
      

3、 下载Android Studio
       http://rj.baidu.com/soft/detail/27390.html?ald

       1)由于下载Android SDK并非易事,需要配置代理或FQ;

       2)在使用中会有各种报错或提示更新sdk等乱七八糟问题,

       因此推荐下载Android Studio (百度软件中心下载速度不错),下载后进行安装,会提示选择SDK安装路径,我们主要使用的就是这个SDK。

       完成安装后向系统Path环境变量中添加两个值。分别是 Android SDK中tools目录的路径和platform-tools的路径。例如:

       C:\Program Files (x86)\Android\android-sdk\tools;
       C:\Program Files (x86)\Android\android-sdk\platform-tools;
Highslide JS
      



4、下载NodeJs并安装

     https://nodejs.org/download/
Highslide JS
      



5、安装Ionic 和 Cordova

    http://ionicframework.com/getting-started/

    运行“CMD” 键入“npm install -g cordova ionic” 根据网络环境,安装的时间有所不同。

npm install -g cordova ionic全局安装,在操作中本项目安装生成apk一直报错


    安装完成后,就可以创建一个Ionic项目“ionic start myApp tabs”

    进入myApp项目 “cd myApp”

    在浏览器中运行 "ionic serve"

    添加安装平台 “ionic platform add android”

    编译成apk “ionic build android”

    直接在手机上进行调试“ionic run”
Aug 5

 原文: What is WebAssembly and why it affects web developers!

你听说过 WebAssembly 吗?这是由 Google , Microsoft , Mozilla , Apple 等几家大公司合作发起的一个关于 面向Web的通用二进制和文本格式 的项目。 现在就让我们来看看WebAssembly到底是个啥?为什么它的出现和未来的发展跟我们每个人都息息相关,即使你并不是一个程序猿/媛~

至少在某种程度上,它将改变Web生态。

JavaScript–Web世界的汇编语言

我们有许多面向Web应用的开发规范,这些设计优良的规范让Web开发者们的工作变得更加的简单。我们很难想象自己所创建和网站或应用没有任何规则、编程语言、框架和开发理念可以遵循。

而将所有这些事情组合到一起的Web规范有一个众所周知的名字: JavaScript !

Aug 4
见过最实在的解释

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
下面就是我的学习笔记,对于Javascript初学者应该是很有用的。
一、变量的作用域
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
  var n=999;
  function f1(){
    alert(n);
  }
  f1(); // 999
另一方面,在函数外部自然无法读取函数内的局部变量。
  function f1(){
    var n=999;
  }
  alert(n); // error
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
  function f1(){
    n=999;
  }
  f1();
  alert(n); // 999
二、如何从外部读取局部变量?
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。
  function f1(){
    var n=999;
    function f2(){
      alert(n); // 999
    }
  }
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,
对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会 "一级一级" 地向上寻找所有父对象的变量。
所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!
  function f1(){
    var n=999;
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
三、闭包的概念
上一节代码中的f2函数,就是闭包。
各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
四、闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
怎么来理解这句话呢?请看下面的代码。
  function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。
这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,
因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。
其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,
所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
五、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),
把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
六、思考题
如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。
代码片段一。
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){//alert(this.name);//My Object
      return function(){
        return this.name;// 空
      };
    }
  };
        alert(this.name);// The Window
  alert(object.getNameFunc()()); // 空

代码片段二。
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()()); // My Object

一层访问一层,不能跨层访问
Jul 29
弹出一个半透明遮罩层,结果点击穿透,能点到层下的按钮,触摸屏能触摸滚动下面的页面,以下解决,拿走不谢!
禁止点击穿透,禁止触摸穿透


css


js

May 13
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information). These methods take one or more function arguments that are called when the $.ajax() request terminates. This allows you to assign multiple callbacks on a single request, and even to assign callbacks after the request may have completed. (If the request is already complete, the callback is fired immediately.) Available Promise methods of the jqXHR object include:

jqXHR.done(function( data, textStatus, jqXHR ) {});
An alternative construct to the success callback option, the .done() method replaces the deprecated jqXHR.success() method. Refer to deferred.done() for implementation details.

jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
An alternative construct to the error callback option, the .fail() method replaces the deprecated .error() method. Refer to deferred.fail() for implementation details.

jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { });
An alternative construct to the complete callback option, the .always() method replaces the deprecated .complete() method.

In response to a successful request, the function's arguments are the same as those of .done(): data, textStatus, and the jqXHR object. For failed requests the arguments are the same as those of .fail(): the jqXHR object, textStatus, and errorThrown. Refer to deferred.always() for implementation details.

jqXHR.then(function( data, textStatus, jqXHR ) {}, function( jqXHR, textStatus, errorThrown ) {});
Incorporates the functionality of the .done() and .fail() methods, allowing (as of jQuery 1.8) the underlying Promise to be manipulated. Refer to deferred.then() for implementation details.

Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

The this reference within all callbacks is the object in the context option passed to $.ajax in the settings; if context is not specified, this is a reference to the Ajax settings themselves.

For backward compatibility with XMLHttpRequest, a jqXHR object will expose the following properties and methods:

readyState
status
statusText
responseXML and/or responseText when the underlying request responded with xml and/or text, respectively
setRequestHeader(name, value) which departs from the standard by replacing the old value with the new one rather than concatenating the new value to the old one
getAllResponseHeaders()
getResponseHeader()
statusCode()
abort()
No onreadystatechange mechanism is provided, however, since done, fail, always, and statusCode cover all conceivable requirements.

Callback Function Queues

The beforeSend, error, dataFilter, success and complete options all accept callback functions that are invoked at the appropriate times.

As of jQuery 1.5, the fail and done, and, as of jQuery 1.6, always callback hooks are first-in, first-out managed queues, allowing for more than one callback for each hook. See Deferred object methods, which are implemented internally for these $.ajax() callback hooks.

The callback hooks provided by $.ajax() are as follows:

beforeSend callback option is invoked; it receives the jqXHR object and the settings object as parameters.
error callback option is invoked, if the request fails. It receives the jqXHR, a string indicating the error type, and an exception object if applicable. Some built-in errors will provide a string as the exception object: "abort", "timeout", "No Transport".
dataFilter callback option is invoked immediately upon successful receipt of response data. It receives the returned data and the value of dataType, and must return the (possibly altered) data to pass on to success.
success callback option is invoked, if the request succeeds. It receives the returned data, a string containing the success code, and the jqXHR object.
Promise callbacks — .done(), .fail(), .always(), and .then() — are invoked, in the order they are registered.
complete callback option fires, when the request finishes, whether in failure or success. It receives the jqXHR object, as well as a string containing the success or error code.

官方文档写的很详细:http://api.jquery.com/jquery.ajax/

注意:complete和error时的textStatus不一样。



Pages: 9/43 First page Previous page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Next page Final page [ View by Articles | List ]