2

我想做一些我认为是使用“咖啡脚本类”和 Angular JS 结构的好方法。

<!doctype html>
<html ng-app>

  <head>
    <meta charset=utf-8>
    <meta name=viewport content="width=device-width, initial-scale=1">
    <title>Main Test</title>
    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
    <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="js/angular.min.js"></script>
    <script type="text/javascript" src="js/coffee.js"></script>
  </head>

  <body>
    <div ng-controller="MainClass" style="margin-left:10px">
      <h2>All todos: {{test()}}</h2>
    </div>
  </body>

</html>

请注意,我将 DIV ng-controller 设置为 MainClass 并在 H2 HTML 标记内绑定 test() 方法。

class AngularJSController
  constructor: ($scope, $main) ->

    $scope.test = MainClass.prototype.test
    MainClass.test = MainClass.prototype.test
    $main.test = MainClass.prototype.test
    test = MainClass.prototype.test
    @test = MainClass.prototype.test

    console.log @test

class MainClass extends AngularJSController
  constructor: ($scope) ->
    super $scope, this

    setTimeout (->
        console.log test()
      ), 1000

    test();

  test: -> 'aloha!'

在 AngularJSController 构造函数中,我尝试了所有我想在 MainClass 范围内设置我的超类方法 TEST 的形式,但没有成功。

我正在尝试这样做,因为我只想在我的 Angular JS 控制器和组件上使用类。

我已经遇到的问题:

  1. 如果我尝试使用@test()而不是test()在 setTimeout 中使用,jQuery 已经用this一种 JQuery Window 对象替换了该属性。

    setTimeout (-> console.log @test()), 1000
    
  2. 我不知道test()调用的真正范围是什么,如果这个地方(或@cause Coffee)与地方任何东西都不一样。

    test() != this.test() != @.test() # the first scope isn't the same scope of last two calls
    
4

6 回答 6

8

我使用了以下语法:

app = angular.module 'myapp', []

class MySimpleCtrl

  @$inject: ['$scope'] 
  constructor: (@scope) ->
    @scope.demo = 'demo value'
    @scope.clearText = @clearText

  clearText: =>
    @scope.demo = ""

app.controller 'MySimpleCtrl', MySimpleCtrl

angular.bootstrap document, ['myapp']

看看这个 jsFiddle:http: //jsfiddle.net/jwcMA/

于 2013-08-12T18:04:49.443 回答
4

这是一个带有基类的通用方法:

http://www.devig.me/angular-dot-js-coffeescript-controller-base-class/

BaseCtrl.coffee

# dependency - Function.prototype.bind or underscore/lodash

app = angular.module 'someApp'

class @BaseCtrl
  @register: (app, name) ->
    name ?= @name || @toString().match(/function\s*(.*?)\(/)?[1]
    app.controller name, @

  @inject: (args...) ->
    @$inject = args

  constructor: (args...) ->
    for key, index in @constructor.$inject
      @[key] = args[index]

    for key, fn of @constructor.prototype
      continue unless typeof fn is 'function'
      continue if key in ['constructor', 'initialize'] or key[0] is '_'
      @$scope[key] = fn.bind?(@) || _.bind(fn, @)

    @initialize?()

BookFormCtrl.coffee

app = angular.module 'someApp'

class BookFormCtrl extends BaseCtrl
  @register app
  # list of dependencies to be injected
  # each will be glued to the instance of the controller as a property
  # e.g. @$scope, @Book
  @inject '$scope', 'Book'

  # initialize the controller
  initialize: ->
    @$scope.book =
      title: "Hello"

  # automatically glued to the scope, with the controller instance as the context/this
  # so usable as <form ng-submit="submit()">
  # methods that start with an underscore are considered as private and won't be glued
  submit: ->
    @Book.post(@$scope.book).then =>
      @$scope.book.title = ""
于 2013-12-31T01:46:31.820 回答
0
  1. setTimeout 与 jQuery 没有任何关系,但传递给 setTimeout 的函数确实在全局(窗口)上下文中执行。使用胖箭头将其显式绑定到当前范围。 http://coffeescript.org/#fat_arrow

    setTimeout (=>
      console.log @test()
    ), 1000
    
  2. 抱歉,我不确定你在问什么。

于 2013-01-11T13:08:11.027 回答
0

在大多数情况下,Angular 确实支持 Coffescript 类!我发现了使用 RequireJs 的问题,需要一个函数而不是一个对象。

看看这里: http: //softwareninjaneer.com/blog/writing-angularjs-controllers-coffeescript-classes/

于 2015-01-20T00:01:43.960 回答
0

我对@malix 的回答并不满意,尽管它确实让我找到了一个可行的解决方案。这是我的做法:

'use strict'

class ImportsCtrl
  constructor: ($scope, Import) ->
    Import.query().then (imports) -> $scope.imports = imports

angular.module("greatDealsApp").controller "ImportsCtrl", ImportsCtrl

这是一个人为的$scope变成 的属性的例子ImportsCtrl

'use strict'

class ImportsCtrl
  constructor: ($scope, Import) ->
    @scope = $scope
    @Import = Import
    @loadImports()

  loadImports: =>
    @Import.query().then (imports) => @scope.imports = imports

angular.module("greatDealsApp").controller "ImportsCtrl", ImportsCtrl

而且我不确定这是否重要,但我正在使用ng-annotate

于 2015-03-11T21:08:38.703 回答
-1

不可能。您不能将控制器设置为对象(MainClass),因为 AngularJS 确保控制器是一个函数。

您需要自定义 AngularJS 才能做到这一点。我认为这不是一个好主意。

参考

于 2013-01-11T12:30:19.250 回答