【问题标题】:Use a "Coffee Script Class" instead of a Method as Angular JS ng-controller使用“咖啡脚本类”而不是方法作为 Angular JS ng-controller
【发布时间】:2015-03-12 05:08:38
【问题描述】:

我想做一些我认为是使用“咖啡脚本类”和 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. 如果我尝试在 setTimeout 中使用 @test() 而不是 test(),jQuery 已经将 this 属性替换为一种 JQuery 窗口对象。

    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
    

【问题讨论】:

  • 您在示例中基本上需要的是一个服务,将可重用的方法附加到控制器,如果您希望该服务成为一个类 AngularJS 不在乎,但控制器应该始终是函数(按设计)。
  • 加缪,我的想法更简单。我只想创建我的类,继承一个简单的基类,让我能够使用 Coffee Script Classes Structure 对我的组件进行编程。只是它!在不改变 Coffee 或 Angular 的任何一种实现方式的情况下,成为与 Coffee 和 Angular 一起使用的简单、有用且非常小的框架。你明白了吗?
  • 有一个很好的解决方案:github.com/lucassus/mongo_browser/blob/…
  • @MarceloFilho 你能接受我的回答吗?

标签: class controller coffeescript angularjs


【解决方案1】:

我使用了以下语法:

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/

【讨论】:

    【解决方案2】:

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

    http://www.devign.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 = ""
    

    【讨论】:

    • 很好的答案。但是 - 此代码中存在一个严重错误,已在上面链接的博客文章中修复。请确保您使用博客文章中的更新代码来避免使用 @$scope 的一些麻烦!
    【解决方案3】:
    1. setTimeout 与 jQuery 没有任何关系,但传递给 setTimeout 的函数确实在全局(窗口)上下文中执行。使用胖箭头将其显式绑定到当前范围。 http://coffeescript.org/#fat_arrow

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        我对@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

        【讨论】:

          【解决方案6】:

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

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

          参考文献

          【讨论】:

          • 我猜你真的不明白这种方法的目的。谢谢。
          • 那么目的是什么?因为你没有提供任何解释。
          • 阅读标题:“使用“咖啡脚本类”而不是方法作为 Angular JS ng-controller”。主要目的是您能够在控制器类中/上使用 Coffee 提供的所有 OO 功能。
          猜你喜欢
          • 2013-02-15
          • 2013-01-09
          • 2013-11-21
          • 1970-01-01
          • 2018-01-25
          • 1970-01-01
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          相关资源
          最近更新 更多