ANgularjs AND WBlog



yafeilee.me

2014.4.5

广告时间


孔雀机构介绍

SZStartup 正在找赞助商


Angularjs 快速指南









向下

双向数据绑定

two ways data binding


git checkout -f step-1






向下

控制器

Controller


git checkout -f step-2






向下

过滤器

Filter


git checkout -f step-3






向下

依赖注入

Dependency Injection

git checkout -f step-5






向下

路由多视图

Routing & Multi Views

git checkout -f step-7






向下

自定义服务

Services

git checkout -f step-11






向下

动画

Animation

git checkout -f step-12






END

整合 Rails


gem 'angularjs-rails'

目录结构:

application.js: require 'angularjs'

创建 angularjs.js.coffee

创建  angularjs 子目录

Angularjs.js.coffee



#= require angular
#= require angular-cookies
#= require angular-resource
#= require angular-sanitize
#= require_self
#= require_tree ./angularjs

@app = angular.module('app', ['ngCookies', 'ngSanitize'])

@app.config(["$httpProvider", (provider) ->
    provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
    provider.defaults.headers.common['Accept'] = 'application/json'
])

controller



@app.controller 'CommentsController', ['$scope', '$http', '$location', '$timeout', ($scope, $http, $location, $timeout)->    url = $location.absUrl() + "/comments.json"

$http.get(url).success (data)->
console.log data
$scope.comments = data

$scope.publish_success = null

vIEWS



#views/layouts/application.html.slim
section.main-section ng-app="app"
    

#views/blogs/_post.html.slim
p ng-controller="LikesController" ng-cloak=""
  button.like-button ng-show="! is_liked " ng-click="submit()"
    |{{ count }}
    span Like
  button.like-button.liked ng-show=" is_liked " ng-click="cancel()"
    |{{ count }}
    span Like

整合完毕


总结步骤:

1. 整合 angularjs-rails
2. 写入 application.js 加载
3. 创建独立目录, 方便维护
4. views 中添加 ng 标签

Happy 的事


效果刚刚的:

NO Server-JS

NO Client-JS

ONLY: 数据绑定


向下

BEFORE



$(this).on 'click', '.add_member_button', (e)->
e.preventDefault()

# 处理选中时的情况
if $('#member_user_id').val() && $('#member_user_id').data('name') == $('#member_user_name').val()
  params = {
    user_id: $('#member_user_id').val(),
    role: $('#member_role').val()
  }
else
  #未选中
  params = {
    name: $('#member_user_name').val(),
    email: $('#member_user_email').val(),
    role: $('#member_role').val(),
  }
url = $('.add_member_div').data('uri')
$.post url, params, (data)->
  Alert.doit data, ()->
    url = $('div.members').data('uri')
    $.get url, (data)->
      $('div.members').html(data)
    $('.add_member_section').empty()
        
        

AFTER



$scope.submit = ->
comment = { content: $scope.content, name: $scope.name, email: $scope.email }
$http.post(url, comment)
.success (res)->
  if res.success
    $scope.publish_success = true
    $scope.content = ''
    $scope.comments.unshift(res.data)
  else
    $scope.publish_success = false
    $scope.publish_fail_msg = res.message
  $timeout ->
    $scope.publish_success = null
  , 3*1000

总结


大量节省 Javascript 编写时间

C 与 M 分离, 便于维护

用后端思维写前端代码, 重构能力强

实例讲解

WBlog

code review

https://github.com/windy/wblog

Angularjs 那些坑儿











向下

依赖声明

before
@app.controller 'xxCtrl', ($scope, $http) ->
    ...
    
after
@app.controller 'xxCtrl', ['$scope', '$http', ($scope, $http) ->
    ...
]

FORM


ng-submit 上不能有 action, 否则无效

可能的话远离 simple_form

HTML片断


插入 HTML 片断要加载 ngSanitize

INPUT 初始化问题


input[text] 标签 value 不能按常规的缺省处理:

http://stackoverflow.com/questions/13769732/angular-js-init-ng-model-from-default-values

不建议使用 ng-init 初始化:

Error: [$parse:lexerr] Lexer Error: Unexpected next character  at columns 5000-5000 [\] in expression

使用 $http 来请求( why? )

条件表达式


要足够的简单

NO window 对象
NO javascript 表达式

所有逻辑放入 controller

删除 COOKIES

与 cofeescript 的冲突( null 与 undefined )

无法使用 $cookies.xx = null 来删除

必须使用 delete $cookies.xx

或者使用:  $cookieStore

事件绑定


image: src -> ng-src
link: href -> ng-href

像 form 一样, 不能有 href, src 等

http://stackoverflow.com/questions/10931315/how-to-preventdefault-on-anchor-tags-in-angularjs

{{ 与 ng-BIND


几乎所有使用 {{ 的地方都需要使用 ng-cloak

或者使用 ng-bind

HTTP


在 post, patch 请求时, 要使用 data 来传参, 而不是 params

原因: params 会直接将数据附在URL上, 造成 451 错误

ANGULARJS 常见场景处理



1. 预传递变量( 讨论 )
2. form 的校验( 讨论 )
3. 防止重复提交( 讨论 )
4. {{}} 体验的处理( 讨论 )
5. ng-click 获取当前元素

预传递变量


例如: 一个表单的 URL 传入控制器

使用 JS 全局变量? 
写在 controller 里?
使用 ng-init 传入?

或者其他更好的办法?

FORM 的校验


如何简洁设计高亮表单错误提示? 

表单错误提示对用户如何友好?

防止重复提交


如何防止用户多次点击

思路? 

{{ 的问题处理


ng-bind

ng-cloak

NG-CLICK 获取当前元素


使用 click(xx, $event) 自动传入


http://stackoverflow.com/questions/12430820/accessing-clicked-element-in-angularjs

其他不爽的


对框架元素支持不足:

bootstrap 3

foundation 5

需要针对加载专门的 directive

MORE


测试

自定义 directive

自定义 filter

自定义 services

BUT


对 Angularjs 内部还是空白

还是个菜鸟

誰来分析其实现

继续努力

工具推荐


1. Dash: 编程文档必备神器 ( Y 120 )

2. Oh-my-zsh GIT 插件:

git commit -> gcgit push -> gp
git checkout -> gco
git merge -> gm

...

谢谢

ANGULARJS

By Li Yafei

ANGULARJS

  • 7,021