devise tree使用_使用Devise和Bootstrap在Rails上设置Angular SPA

devise tree使用

Setting Up an Angular SPA on Rails with Devise and Bootstrap

This article was originally published at jessenovotny.com.

本文最初发表在jessenovotny.com上

When I started programming my very first Angular single page application (SPA), I noticed the resources for setup and integration with Devise to be thin or fragmented. The most useful guide I found was actually just a segment of a general Angular with Rails walkthrough. There were other resources that were either too complex or advanced, and they didn’t really go through the initial baby steps. One of the most daunting challenges for a new programmer is starting from scratch. I know, because I’m one of these folks.

当我开始对第一个Angular单页应用程序(SPA)进行编程时,我注意到用于与Devise进行设置和集成的资源很少或很零散。 我发现最有用的指南实际上只是通用Angular with Rails演练的一部分。 还有其他资源太复杂或太高级,它们实际上并没有经过最初的初级步骤。 对于新程序员来说,最艰巨的挑战之一是从头开始。 我知道,因为我是这些人之一。

Most of what I’ve learned through my online course has been delivered in small, increasingly more advanced components. I open a lab, and the groundwork is already laid out, so there isn’t a ton of practice in setting up an app from a blank slate. For the sake of course completion time, this makes sense. Besides, you only need to build a couple apps from the ground up to get a feel for how it’s done. If you haven’t gotten there yet, this walkthrough will be right up your alley.

我从在线课程中学到的大部分内容都是通过小型的,越来越先进的组件提供的。 我开设了一个实验室,并且基础工作已经准备就绪,因此从空白开始设置应用程序并没有太多实践。 为了完成课程,这很有意义。 此外,您只需要从头开始构建几个应用程序即可了解它的完成方式。 如果您还没到那儿,那么这个演练将就在您的小巷。

Once I finally got all the pieces working and my first Angular project was up and running, I felt it pertinent to give back to the community. Since I currently don’t have enough “reputation points” to answer questions on Stack Overflow, the next best thing would be to make my own walkthrough for setting up an Angular SPA on Rails with Devise and Bootstrap. The following is exactly what I wish I had found in my initial research on the topic.

当我终于完成所有工作,并且我的第一个Angular项目启动并运行后,我觉得回馈社区是很重要的。 由于我目前没有足够的“信誉点”来回答有关Stack Overflow的问题,因此,下一个最好的事情就是自己动手,在带有Devise和Bootstrap的Rails上设置Angular SPA。 以下正是我希望对该主题进行初步研究时发现的。

Granted, a huge part of web development is being able to solve complex problems without being handed the solution. I feel that sometimes a new developer just needs a helping hand. So here it is.

当然,Web开发的很大一部分就是能够解决复杂的问题而无需交付解决方案。 我觉得有时候新开发者只需要伸出援手。 就是这样

入门 (Getting Started)

This guide is meant to be a diving board for getting started. It assumes you already have a basic understanding of Angular, Rails, Devise, and Bootstrap. I chose to not explore Active Record, but I do touch on Active Model Serializer, as it’s necessary for sending models to your JavaScript front end. There’s much more to learn about this subject and that would warrant its own series of guides. Likewise, I only go into installing Bootstrap to the point where I can verify it’s working.

本指南旨在成为入门的跳水板。 假定您已经对Angular,Rails,Devise和Bootstrap有基本的了解。 我选择不探索Active Record,但是我确实接触了Active Model Serializer,因为将模型发送到JavaScript前端是必需的。 关于这个主题,还有很多要学习的知识,这将保证它拥有自己的一系列指南。 同样,我只需要安装Bootstrap即可验证它是否正常工作。

Feel free to read along with the video I created for this tutorial:

随时阅读我为本教程创建的视频:

配置 (Setting up)

To get started, you want to open Terminal and navigate to the folder where you want to create your new application. In this demonstration, I’m on the Desktop.

首先,您要打开终端并导航到要在其中创建新应用程序的文件夹。 在此演示中,我在桌面上。

In Terminal, you will run $ rails new YOUR-APP which initializes Rails, creates a directory with the entire framework, and bundles all of the baked in gems. (In case you’re unfamiliar, $ denotes a Terminal command.)

在Terminal中,您将运行$ rails new YOUR-APP ,它将初始化Rails,创建带有整个框架的目录,并将所有烘焙的宝石捆绑在一起。 (如果您不熟悉, $表示终端命令。)

Open your Gemfile, remove gem 'turbolinks' and add the following:

打开您的Gemfile ,删除Gemfile gem 'turbolinks'并添加以下内容:

gem 'bower-rails'
gem 'devise'
gem 'angular-rails-templates' #=> allows us to place our html views in the assets/javascripts directory
gem 'active_model_serializers'
gem 'bootstrap-sass', '~> 3.3.6' #=> bootstrap also requires the 'sass-rails' gem, which should already be included in your gemfile

While Bower isn’t essential to this project, I chose to use it for one simple reason: experience. Sooner or later, I’ll probably find myself working on an app that was built with Bower, so why not start playing with it now?

尽管Bower对该项目不是必不可少的,但出于一个简单的原因,我选择使用它:经验。 迟早,我可能会发现自己正在使用Bower构建的应用程序上工作,那么为什么不立即开始玩呢?

What is Bower? You can learn more on their website, bower.io, but as far as I can tell, it’s essentially a package manager just like Ruby gems or npm. You can install it with npm, but I chose to include the bower-rails gem for this guide.

什么是凉亭? 您可以在他们的网站bower.io上了解更多信息,但是据我所知,它实际上是一个软件包管理器,就像Ruby gems或npm一样。 您可以使用npm安装它,但是我选择在本指南中包括bower-rails gem。

初始化宝石,创建数据库和添加迁移 (Initializing the Gems, Creating a Database and Adding a Migration)

Now we’re going to install/initialize these gems, create our database, add a migration so users can sign up with a username, and then apply these migrations to our schema with the following commands:

现在,我们将安装/初始化这些gem,创建数据库,添加迁移,以便用户可以使用用户名进行注册,然后使用以下命令将这些迁移应用于我们的模式:

$ bundle install
$ rake db:create #=> create database
$ rails g bower_rails:initialize json  #=> generates bower.json file for adding "dependencies"
$ rails g devise:install #=> generates config/initializers/devise.rb, user resources, user model, and user migration with a TON of default configurations for authentication
$ rails g migration AddUsernametoUsers username:string:uniq #=> generates, well, exactly what it says.
$ rake db:migrate

By the time you’ve got momentum building out your app, you’ll likely have many more dependencies or “packages”, but here’s what you’ll need to get started. Add the following vendor dependencies to bower.json:

等到您有能力开发自己的应用程序时,您可能会拥有更多的依赖项或“程序包”,但这就是开始所需要的。 将以下供应商依赖项添加到bower.json

...
"vendor": {
  "name": "bower-rails generated vendor assets",
  "dependencies": {
    "angular": "v1.5.8",
    "angular-ui-router": "latest",
    "angular-devise": "latest"
  }
}

Once you’ve saved those changes in bower.json, you’ll want to install those packages with the following command and then generate your user serializer from the ‘active-model-serializer’ gem installed earlier:

将这些更改保存在bower.json中之后,您将需要使用以下命令安装这些软件包,然后从之前安装的'active-model-serializer'gem生成用户序列化器:

$ rake bower:install
$ rails g serializer user

Look for app/serializers/user_serializer.rb and add , :username directly after attributes :id so that when Devise requests the user’s information from Rails, you can display their chosen username. This is much nicer than saying “Welcome, jesse@email.com” or worse, “Welcome, 5UPer$3CREtP4SSword”. Just kidding, but seriously, don’t do that.

查找app / serializers / user_serializer.rb并在attributes :id之后直接添加, :username ,以便在Devise向Rails请求用户信息时,可以显示其选择的用户名。 这比说“ Welcome,jesse@email.com”好得多,或者说“ Welcome,5UPer $ 3CREtP4SSword”好得多。 只是开玩笑,但认真的是,不要那样做。

Add the following in config/application.rb directly under class Application < Rails::Application:

将以下内容直接添加到config/application.rb class Application < Rails::Application

config.to_prepare do
  DeviseController.respond_to :html, :json
end

Since Angular will request information about the user using .json, we need to make sure the DeviseController will respond appropriately, which it doesn’t do by default.

由于角将使用要求有关用户的信息.json ,我们需要确保DeviseController会做出适当的React,它默认情况下不这样做。

完成后端设置 (Completing the Back-end Setup)

We’re getting soooo close to finishing our back-end. Just a few more adjustments …

我们正在SOOOO即将完成我们的后端。 再进行一些调整...

Open config/routes.rb and add the following line under devise_for :users: root 'application#index'. Then replace the contents of app/controllers/application_controller.rb with this whole snippet:

打开config/routes.rb并在devise_for :users下添加以下行devise_for :users root 'application#index' 。 然后,使用以下完整代码段替换app/controllers/application_controller.rb的内容:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?
  skip_before_action :verify_authenticity_token

  respond_to :json

  def index
    render 'application/index'
  end

  protected

  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end

We’ve done a few things here. First, we’re telling Rails that :json is our friend; our only view lives in views/application/index.html.erb; don’t worry about authenticity tokens when you get a call from Devise; oh, and our user will have a username.

我们在这里做了一些事情。 首先,我们告诉Rails :json是我们的朋友; 我们唯一的视图位于views/application/index.html.erb ; 当您从Devise接到电话时,不必担心真实性令牌; 哦,我们的用户将有一个用户名。

Next open app/controllers/users_controller.rb and make sure you can access the user in JSON format with any /users/:id.json request:

接下来打开app/controllers/users_controller.rb并确保您可以使用任何/users/:id.json请求以JSON格式访问用户:

class UsersController < ApplicationController
  def show
    user = User.find(params[:id])
    render json: user
  end  
end

Don’t worry about setting up the :show resource in routes.rb. Devise has done this for us already!

不用担心在routes.rb设置:show资源。 Devise已经为我们做到了!

By default, Rails will initialize with views/layouts/application.html.erb, but we don’t want that (or rather, I don’t want this), so do the following:

默认情况下,Rails将使用views/layouts/application.html.erb初始化,但是我们不希望这样做(或者,我不希望这样做),因此请执行以下操作:

  • Move that file to app/views/application/.

    此举文件, app/views/application/

  • Rename it to index.html.erb.

    将其重命名为index.html.erb

  • Replace <%= yield %> with <ui-view></ui-view> (we won’t be rendering any erb aside from the script/style tags in our header).

    <%= yield %>替换为<ui-view></ui-view> (除了标题中的脚本/样式标签之外,我们不会渲染任何erb)。

  • Remove any mention of “turoblinks” in the script and stylesheet erb tags.

    删除脚本和样式表erb标签中对“ turoblinks”的任何提及。
  • Add ng-app="myApp" as an attribute to the <body> tag. When we launch our server, Angular will load and frantically search our DOM for this before initializing our app.

    ng-app="myApp"作为属性添加到<body>标签。 当我们启动服务器时,Angular将在初始化我们的应用程序之前加载并疯狂地在DOM中搜索此内容。

The final step to getting our back end configured is laying out our asset pipeline. Bower has already installed a bunch of stuff for us in vendor/assets/bower_components. Likewise, we installed a bunch of sweet gems earlier. Let’s make sure our app can find these scripts and stylesheets:

配置后端的最后一步是布置资产管道。 Bower已经在vendor/assets/bower_components为我们安装了很多东西。 同样,我们之前安装了许多甜美的宝石。 确保我们的应用程序可以找到以下脚本和样式表:

Require the following in app/assets/javascripts/application.js:

app/assets/javascripts/application.js要求以下内容:

//= require jquery
//= require jquery_ujs
//= require angular
//= require angular-ui-router
//= require angular-devise
//= require angular-rails-templates
//= require bootstrap-sprockets
//= require_tree .

Note: don’t forget to remove require turbolinks

注意:别忘了删除require turbolinks

Finally, we must rename app/assets/stylesheets/application.css to application.scss and add these two @import lines at the end of our stylesheet:

最后,我们必须将app/assets/stylesheets/application.css重命名为application.scss并在样式表的末尾添加这两条@import行:

*
 *= require_tree .
 *= require_self
 */
@import "bootstrap-sprockets";
@import "bootstrap";

Boom!! Now we have everything set up and we can start working on our front end.

繁荣!! 现在我们已完成所有设置,我们可以开始进行前端工作了。

前端 (The Front End)

Here’s a preview of what our Angular application tree will look like. Since we installed the ‘angular-templates’ gem, we can keep all of our HTML files in the assets/javascripts directory with all of our other Angular files:

这是Angular应用程序树的外观预览。 由于我们安装了“ angular-templates” gem,因此我们可以将所有HTML文件和所有其他Angular文件保留在assets/javascripts目录中:

/javascripts/controllers/AuthCtrl.js
/javascripts/controllers/HomeCtrl.js
/javascripts/controllers/NavCtrl.js
/javascripts/directives/NavDirective.js
/javascripts/views/home.html
/javascripts/views/login.html
/javascripts/views/register.html
/javascripts/views/nav.html
/javascripts/app.js
/javascripts/routes.js

First things first: let’s declare our application in app.js and inject the necessary dependencies:

首先,首先要在app.js声明我们的应用程序,并注入必要的依赖项:

(function(){
  angular
    .module('myApp', ['ui.router', 'Devise', 'templates'])
}())

I’m using an IIFE here, for reasons explained in this quote:

我在这里使用IIFE,原因如下:

Wrapping your AngularJS components in an Immediately Invoked Function Expression (IIFE). This helps to prevent variables and function declarations from living longer than expected in the global scope, which also helps avoid variable collisions. This becomes even more important when your code is minified and bundled into a single file for deployment to a production server by providing variable scope for each file. Codestyle.co AngularJS Guide

将AngularJS组件包装在立即调用的函数表达式(IIFE)中。 这有助于防止变量和函数声明在全局范围内的寿命超出预期,这也有助于避免变量冲突。 当您的代码经过精简并捆绑到一个文件中以通过为每个文件提供可变作用域来部署到生产服务器时,这一点变得尤为重要。 Codestyle.co AngularJS指南

Routes.js (Routes.js)

Next, we’re going to stub out our routes.js file. Some of this is a step ahead of where we are now, but I’d rather get it out of the way now than come back:

接下来,我们将routes.js文件。 其中一些步骤比我们现在要领先,但我宁愿现在就摆脱它,也不要回来:

angular
  .module('myApp')
  .config(function($stateProvider, $urlRouterProvider){
    $stateProvider
      .state('home', {
        url: '/home',
        templateUrl: 'views/home.html',
        controller: 'HomeCtrl'
      })
      .state('login', {
        url: '/login',
        templateUrl: 'views/login.html',
        controller: 'AuthCtrl',
        onEnter: function(Auth, $state){
          Auth.currentUser().then(function(){
            $state.go('home')
          })
        }
      })
      .state('register', {
        url: '/register',
        templateUrl: 'views/register.html',
        controller: 'AuthCtrl',
        onEnter: function(Auth, $state){
          Auth.currentUser().then(function(){
            $state.go('home')
          })
        }
      })
    $urlRouterProvider.otherwise('/home')
  })

What we’ve just done is called our angular app ‘myApp’, and called the config function, passing in $stateProvider and $routerUrlProvider as parameters. Immediately we can call $stateProvider and start chaining .state() methods, which take two parameters, the name of the state (‘home’ for example), and an object of data that describes the state, such as its URL, HTML template, and which controller to use. We’re also using $urlRouterProvider just to make sure that the user can’t navigate anywhere but to our predetermined states.

我们刚刚完成的工作称为角度应用程序“ myApp”,并称为配置函数,将$stateProvider$routerUrlProvider作为参数$routerUrlProvider 。 立即我们可以调用$stateProvider并开始链接.state()方法,该方法.state()两个参数,状态的名称(例如“ home”)和描述状态的数据对象,例如其URL,HTML模板,以及要使用的控制器。 我们还使用$urlRouterProvider来确保用户只能导航到我们的预定状态。

A few things you may not yet be familiar with up to this point are onEnter, $state, and Auth. We’ll get to that later.

onEnter ,您可能还不熟悉的一些内容是onEnter$stateAuth 。 我们稍后再讨论。

Now, let’s build our home.html and HomeCtrl.js:

现在,让我们构建我们的home.htmlHomeCtrl.js

<div class="col-lg-8 col-lg-offset-2">
<h1>{{hello}}</h1>
<h3 ng-if="user">Welcome, {{user.username}}</h3>
</div>
angular
  .module('myApp')
  .controller('HomeCtrl', function($scope, $rootScope, Auth){
    $scope.hello = "Hello World"
  })

You may want to comment the login/register states and run $ rails s to make sure everything’s working. If it is, you’ll see a big beautiful “Hello World”. If it’s right at the top towards the middle, take a deep breath of relief, because Bootstrap is kicking in and that col-lg stuff is positioning it nicely rather than being stuck in the top left corner.

您可能需要注释登录/注册状态并运行$ rails s ,以确保一切正常。 如果是这样,您会看到一个美丽的“ Hello World”。 如果它正好位于顶部的中间位置,请深呼吸,因为Bootstrap正在插入,并且col-lg物品将其放置在很好的位置,而不是卡在左上角。

What Angular has done is searched the DOM, found the attribute ng-app, initialized “myApp”, navigated to /home by default from our router, located the <ui-view> directive, instantiated our HomeCtrl, injected the $scope object, added a key of hello, assigned it a value of "Hello World", and then rendered home.html with this information within the <ui-view> element. Once in the view, Angular scans for any meaningful commands such as the {{...}} bindings and the ng-if directive and renders the controller’s information as needed. I will admit the order of these operations may be off slightly, but you get the gist of what’s going on under the hood.

Angular完成的工作是搜索DOM,找到属性ng-app ,初始化为“ myApp”,默认情况下从我们的路由器导航到/home ,位于<ui-view>指令,实例化HomeCtrl ,注入了$scope对象,添加了一个hello键,为其分配了"Hello World"值,然后使用<ui-view>元素中的此信息呈现了home.html 。 进入视图后,Angular会扫描任何有意义的命令,例如{{...}}绑定和ng-if指令,并根据需要呈现控制器的信息。 我承认这些操作的顺序可能会略有偏离,但是您可以了解幕后情况。

建立AuthCtrl.js和login.html / register.html文件 (Building Out AuthCtrl.js and login.html/register.html Files)

Since we’ve got all of this nitty gritty behind the scenes information out of the way, let’s build out our AuthCtrl.js and login.html/register.html files:

由于我们已经将所有这些AuthCtrl.js信息隐藏在了后面,所以让我们构建AuthCtrl.jslogin.html / register.html文件:

# login.html
<div class="col-lg-8 col-lg-offset-2">
  <h1 class="centered-text">Log In</h1>
  <form ng-submit="login()">
    <div class="form-group">
      <input type="email" class="form-control" placeholder="Email" ng-model="user.email" autofocus>
    </div>
    <div class="form-group">
      <input type="password" class="form-control" placeholder="Password" ng-model="user.password">
    </div>
    <input type="submit" class="btn btn-info" value="Log In">
  </form>
</div>
# register.html
<div class="col-lg-8 col-lg-offset-2">
  <h1 class="centered-text">Register</h1>
  <form ng-submit="register()">
    <div class="form-group">
      <input type="email" class="form-control" placeholder="Email" ng-model="user.email" autofocus>
    </div>
    <div class="form-group">
      <input type="username" class="form-control" placeholder="Username" ng-model="user.username" autofocus>
    </div>
    <div class="form-group">
      <input type="password" class="form-control" placeholder="Password" ng-model="user.password">
    </div>
    <input type="submit" class="btn btn-info" value="Log In">
  </form>
  <br>

  <div class="panel-footer">
    Already signed up? <a ui-sref="home.login">Log in here</a>.
  </div>
</div>

Before I overwhelm you with the AuthCtrl, I just want to point out that most of what you’re seeing are Bootstraped CSS classes so that you’re all super impressed with how beautifully this renders. Ignore all of the class attributes, and everything else should be pretty familiar, such as ng-submit, ng-model, and ui-sref, which takes the places of our usual href anchor tag attribute. Now for the AuthCtrl … are you ready?

在我用AuthCtrl让您不知所措之前,我只想指出,您所看到的大部分都是Bootstraped CSS类,因此您对这些渲染的精美程度都印象深刻。 忽略所有的类属性,其他所有内容都应该非常熟悉,例如ng-submitng-modelui-sref ,它们ui-sref了我们通常的href锚标记属性。 现在使用AuthCtrl…准备好了吗?

angular
  .module('myApp')
  .controller('AuthCtrl', function($scope, $rootScope, Auth, $state){
    var config = {headers: {'X-HTTP-Method-Override': 'POST'}}

    $scope.register = function(){
      Auth.register($scope.user, config).then(function(user){
        $rootScope.user = user
        alert("Thanks for signing up, " + user.username);
        $state.go('home');
      }, function(response){
        alert(response.data.error)
      });
    };

    $scope.login = function(){
      Auth.login($scope.user, config).then(function(user){
        $rootScope.user = user
        alert("You're all signed in, " + user.username);
        $state.go('home');
      }, function(response){
        alert(response.data.error)
      });
    }
  })

Most of this code is derived from the Angular Devise documentation, so I won’t go into too much detail. What you need to know now is that Auth is the service created by angular-device, and it comes with some pretty awesome functions, such as Auth.login(userParameters, config) and Auth.register(userParameters, config). These create a promise, which returns the logged in user once resolved.

这些代码大部分来自Angular Devise文档 ,因此我不会赘述。 您现在需要知道的是Auth是由angular-device创建的服务,它具有一些非常出色的功能,例如Auth.login(userParameters, config)Auth.register(userParameters, config) 。 这些创建承诺,一旦解决,将返回登录的用户。

I’ll admit that I’ve cheated a bit here and assigned that user to the $rootScope. However, a better performing, more scalable approach would be to create a UserService, store the user there, and then inject UserService into any of your controllers that need the user. For the sake of brevity, I also used a simple alert() function in lieu of integrating ngMessages or another service like ngFlash to make announcements about errors or successful login events.

我承认我在这里已经作弊,并将该用户分配给$rootScope 。 但是,一种性能更好,可扩展性更好的方法是创建一个UserService,在其中存储用户,然后将UserService注入需要该用户的任何控制器中。 为了简洁起见,我还使用了一个简单的alert()函数来代替集成ngMessages或其他服务(例如ngFlash来发布有关错误或成功登录事件的公告。

The rest should be pretty self explanatory. The ng-submit forms are attached to these $scope functions, $scope.user is pulling the information from the ng-models on the form inputs, and $state.go() is a nifty function for redirecting to another state.

其余的应该是很自我解释的。 ng-submit表单附加到这些$scope函数上, $scope.user正在从表单输入上的ng-model提取信息,而$state.go()是一个用于重定向到另一个状态的漂亮函数。

If you go back to routes.js now, all of that onEnter logic should make a lot more sense.

如果您现在返回routes.js ,那么所有的onEnter逻辑都应该更有意义。

汇集全部 (Bringing It All Together)

I saved the best for last, so let’s build a fancy little NavDirective.js and nav.html to bring everything together:

我把最好的nav.html到了最后,所以让我们构建一个漂亮的NavDirective.jsnav.html来将所有内容组合在一起:

angular
  .module('myApp')
  .directive('navBar', function NavBar(){
    return {
      templateUrl: 'views/nav.html',
      controller: 'NavCtrl'
    }
})
<div class="col-lg-8 col-lg-offset-2">
  <ul class="nav navbar-nav" >
    <li><a ui-sref="home">Home</a></li>
    <li ng-hide="signedIn()"><a ui-sref="login">Login</a></li>
    <li ng-hide="signedIn()"><a ui-sref="register">Register</a></li>
    <li ng-show="signedIn()"><a ng-click="logout()">Log Out</a></li>
  </ul>
</div>

And the more robust NavCtrl.js:

还有更强大的NavCtrl.js

angular
  .module('myApp')
  .controller('NavCtrl', function($scope, Auth, $rootScope){
    $scope.signedIn = Auth.isAuthenticated;
    $scope.logout = Auth.logout;

    Auth.currentUser().then(function (user){
      $rootScope.user = user
    });

    $scope.$on('devise:new-registration', function (e, user){
      $rootScope.user = user
    });

    $scope.$on('devise:login', function (e, user){
      $rootScope.user = user
    });

    $scope.$on('devise:logout', function (e, user){
      alert("You have been logged out.")
      $rootScope.user = undefined
    });
  })

All we’re doing here is setting up the functions to use in the navigation links such as ng-hide="signedIn()" and ng-click="logout()" and adding listeners to the $scope so that we can trigger actions when certain devise specific events occur. We’re also calling Auth.currentuser() so that when this controller is instantiated, we can double check our $rootScope.user object and display the proper nav links.

我们在这里所做的就是设置要在导航链接中使用的函数,例如ng-hide="signedIn()"ng-click="logout()" ,并将侦听器添加到$scope以便我们可以触发当某些特定devise事件发生时的动作。 我们还调用Auth.currentuser()以便在实例化此控制器时,我们可以Auth.currentuser()检查$rootScope.user对象并显示正确的导航链接。

Let’s find app/views/application/index.html again and add <nav-bar></nav-bar> on the line above <ui-view>. Since this isn’t tied to any of the routes, it will always render above our main content.

让我们再次找到app/views/application/index.html ,并在<ui-view>上方的行上添加<nav-bar></nav-bar> <ui-view> 。 由于这与任何路线无关,因此它将始终在我们的主要内容之上呈现。

Go ahead and refresh your page now. Don’t you love it when things just work? Hopefully you don’t have any weird issues with an out of date bundle, version of Ruby, or something funky like that. Just remember, Google is your best friend.

继续并立即刷新页面。 当事情正常时,您不喜欢它吗? 希望您不会对过时的捆绑包,Ruby版本或类似的时髦东西没有任何奇怪的问题。 请记住,Google是您最好的朋友。

Anyhoo, I hope this has helped! Please leave any questions, comments, or suggestions below!

Anyhoo,希望对您有所帮助! 请在下面留下任何问题,评论或建议!

翻译自: https://www.sitepoint.com/setting-up-an-angular-spa-on-rails-with-devise-and-bootstrap/

devise tree使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值