Angularjs in rails:添加数据到数据库并显示,而不需要重新加载



在一个rails项目中,我通过http.post从angularjs控制器添加数据到数据库。我有下面的代码来做到这一点:

RestaurantIndexCtrl.js.coffee:

restauranteur.controller 'RestaurantIndexCtrl', ['$scope', '$location', '$http', ($scope, $location, $http) ->
$scope.restaurants = []
  $http.get('./restaurants.json').success((data) ->
    $scope.restaurants = data
  )
  $scope.addRestaurant = (test) ->
    $http({
      url: '/restaurants#create',
      method: "POST",
      data: JSON.stringify({name:test}),
      headers: {'Content-Type': 'application/json'}
    })
]

templates/restaurants/index.html:

<form ng-submit="addRestaurant(restaurant.name)">
    <input type="text" ng-model="restaurant.name">
    <button>Register</button>
</form>
<ul ng-repeat="restaurant in restaurants">
    <li><a ng-click="viewRestaurant(restaurant.id)">{{ restaurant.name }}</a></li>
</ul>

和下面的代码在rails项目:restaurants_controller.rb:

def create
    @restaurant = Restaurant.new(restaurant_params)
    respond_to do |format|
      if @restaurant.save
        format.html { redirect_to @restaurant, notice: 'Restaurant was successfully created.' }
        format.json { render action: 'show', status: :created, location: @restaurant }
      else
        format.html { render action: 'new' }
        format.json { render json: @restaurant.errors, status: :unprocessable_entity }
      end
    end
  end

现在,当我完成textfield并将数据发布到rails项目时,数据不会添加到数据库中,直到我刷新页面。当我刷新时,数据被添加到数据库中,并在index.html上显示数据。

  1. 我想当我完成textfield并通过angularjs post到rails控制器时,新数据被添加到数据库并显示在index.html上而无需重新加载。我该怎么做呢?问题是存在于rails控制器或angularjs代码?

  2. 我设置unique validationrestaurant name,现在如果我发送一个存在于数据库中的名称,rails控制器不允许向数据库添加数据。我怎么能得到错误,rails生成并显示给用户在angularjs html代码?

Note:我使用外部视图的angularjs和把模板在public文件夹,然后路由url的ngRoute

main.js.coffee:

@restauranteur = angular.module('restauranteur', ['ngRoute'])
@restauranteur.config(['$routeProvider', ($routeProvider) ->
  $routeProvider
  .when('/restaurants', {
    templateUrl: '../templates/restaurants/index.html',
    controller: 'RestaurantIndexCtrl'
  })
    .otherwise({
        templateUrl: '../templates/home.html',
        controller: 'HomeCtrl'
      })
])

一种方法是让您的create方法返回更新的@restaurants,然后在角端回调中更新范围。真正的粗略实现:

def create
    @restaurant = Restaurant.new(restaurant_params)
    if @restaurant.save
      render json: Restaurant.all, status: 200
    else
      #whatever
    end
  end
end

和在前端:

$scope.addRestaurant = function(test) {
  var data = {name: test}
  $http.post('/restaurants', data).success(function(data){
    $scope.restaurants = data;
  })
}

避免到服务器的往返的另一种方法是假设成功并将新对象推入客户端现有的$scope.restaurants。由于您的验证,这会产生一些问题。

对于验证,错误已经在控制器中呈现了:

format.json { render json: @restaurant.errors, status: :unprocessable_entity }

您必须在$http调用中添加.error处理程序,并将返回的数据设置为$scope.errors或其他内容以显示给用户。

你可能还想把你的api调用抽象到一个angular服务中,这样你就可以在应用的其他部分重用这些代码。还可以考虑阅读$routeProviderresolve属性,并在加载视图之前使用它来解析数据。

相关内容

最新更新