加载更多功能实现
This commit is contained in:
parent
2e8cba59e2
commit
608ae89097
2
Gemfile
2
Gemfile
|
@ -35,7 +35,6 @@ end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara'
|
gem 'capybara'
|
||||||
gem 'factory_girl'
|
|
||||||
gem 'mongoid-rspec', :require => false
|
gem 'mongoid-rspec', :require => false
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
end
|
end
|
||||||
|
@ -43,4 +42,5 @@ end
|
||||||
group :test, :development do
|
group :test, :development do
|
||||||
gem "rspec-rails", ">= 2.8.1"
|
gem "rspec-rails", ">= 2.8.1"
|
||||||
gem 'pry-rails'
|
gem 'pry-rails'
|
||||||
|
gem 'factory_girl_rails'
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,4 +8,5 @@
|
||||||
|
|
||||||
@app.config(["$httpProvider", (provider) ->
|
@app.config(["$httpProvider", (provider) ->
|
||||||
provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||||
|
provider.defaults.headers.common['Accept'] = 'application/json'
|
||||||
])
|
])
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
@app.controller 'ArchivesController', ($scope, $http, $location, $timeout)->
|
||||||
|
url = "/archives.json"
|
||||||
|
$http.get(url).success (res)->
|
||||||
|
$scope.start_with = res.start_with
|
||||||
|
$scope.posts = res.posts
|
||||||
|
|
||||||
|
$scope.no_more_flag = false
|
||||||
|
$scope.loading_flag = false
|
||||||
|
|
||||||
|
$scope.load = ()->
|
||||||
|
$scope.loading_flag = true
|
||||||
|
$http(
|
||||||
|
url: url
|
||||||
|
method: 'GET'
|
||||||
|
params:
|
||||||
|
start_with: $scope.start_with
|
||||||
|
).success (res)->
|
||||||
|
$scope.no_more_flag = true if res.posts.length == 0
|
||||||
|
$scope.start_with = res.start_with
|
||||||
|
$scope.posts = $scope.posts.concat(res.posts)
|
||||||
|
$timeout ->
|
||||||
|
$scope.loading_flag = false
|
||||||
|
, 500
|
||||||
|
$timeout ->
|
||||||
|
$scope.no_more_flag = false
|
||||||
|
, 3000
|
||||||
|
|
||||||
|
$scope.visit = (id)->
|
||||||
|
window.location.href = ("/blogs/" + id)
|
|
@ -1,5 +1,5 @@
|
||||||
@app.controller 'CommentsController', ($scope, $http, $location)->
|
@app.controller 'CommentsController', ($scope, $http, $location, $timeout)->
|
||||||
url = $location.absUrl() + "/comments"
|
url = $location.absUrl() + "/comments.json"
|
||||||
|
|
||||||
$http.get(url).success (data)->
|
$http.get(url).success (data)->
|
||||||
console.log data
|
console.log data
|
||||||
|
|
|
@ -37,4 +37,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-more-field p {
|
||||||
|
text-align: center;
|
||||||
|
color: #444444;
|
||||||
|
border-bottom: 1px solid #DDDDDD;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
protect_from_forgery
|
protect_from_forgery
|
||||||
|
|
||||||
|
helper_method :format_time, :format_date
|
||||||
|
|
||||||
|
def format_time(time)
|
||||||
|
time.strftime("%Y-%m-%d %H:%M")
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_date(time)
|
||||||
|
time.strftime("%Y-%m-%d")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,59 @@
|
||||||
class ArchivesController < ApplicationController
|
class ArchivesController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@posts = Post.all
|
type = map[archive_params[:type]]
|
||||||
|
limit = 10
|
||||||
|
start_with = archive_params[:start_with]
|
||||||
|
@posts = Post.limit(limit).desc(:created_at)
|
||||||
|
if type
|
||||||
|
@posts = @posts.where(type: type)
|
||||||
|
end
|
||||||
|
|
||||||
|
if start_with
|
||||||
|
@posts = @posts.where(:created_at.lt => Time.at(start_with.to_i))
|
||||||
|
end
|
||||||
|
|
||||||
|
#update start_with
|
||||||
|
unless @posts.empty?
|
||||||
|
start_with = @posts[-1].created_at.to_i.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
render :json => {
|
||||||
|
posts: @posts.collect { |post| build_summary(post) },
|
||||||
|
start_with: start_with
|
||||||
|
}
|
||||||
|
end
|
||||||
|
format.html
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def archive_params
|
def archive_params
|
||||||
params.permit(:type)
|
params.permit(:type, :start_with)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def map
|
||||||
|
{
|
||||||
|
"life"=> "生活",
|
||||||
|
"tech"=> "技术",
|
||||||
|
"creator"=> "创业"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def archive_params
|
||||||
|
params.permit(:type, :start_with, :format)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_summary(post)
|
||||||
|
{
|
||||||
|
title: post.title,
|
||||||
|
type: post.type,
|
||||||
|
created_at: format_date(post.created_at),
|
||||||
|
id: post.id.to_s,
|
||||||
|
liked_count: post.likes.size,
|
||||||
|
visited_count: post.visited_count,
|
||||||
|
labels: post.labels_content
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,17 +13,9 @@ class BlogsController < ApplicationController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@post = Post.find(params[:id])
|
@post = Post.find(params[:id])
|
||||||
@prev = Post.where(:created_at.lt => @post.created_at).desc(:created_at).where(:id.ne => @post.id).first
|
created_at = Time.at(@post.created_at.to_f)
|
||||||
@next = Post.where(:created_at.gt => @post.created_at).asc(:created_at).where(:id.ne => @post.id).first
|
@prev = Post.where(:created_at.lt => created_at).desc(:created_at).first
|
||||||
|
@next = Post.where(:created_at.gt => created_at).asc(:created_at).first
|
||||||
@comments = @post.comments
|
@comments = @post.comments
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
def map
|
|
||||||
{
|
|
||||||
"life"=> "生活",
|
|
||||||
"tech"=> "技术",
|
|
||||||
"creator"=> "创业"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,10 +23,6 @@ class CommentsController < ApplicationController
|
||||||
params.permit(:content, :name, :email)
|
params.permit(:content, :name, :email)
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_time(time)
|
|
||||||
time.strftime("%Y-%m-%d %H:%M")
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_json(comment)
|
def build_json(comment)
|
||||||
{
|
{
|
||||||
content: comment.content,
|
content: comment.content,
|
||||||
|
|
|
@ -37,4 +37,8 @@ class Post
|
||||||
def sub_content
|
def sub_content
|
||||||
HTML_Truncator.truncate(content_html,100)
|
HTML_Truncator.truncate(content_html,100)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def labels_content
|
||||||
|
self.labels.collect { |label| label.name }.join(", ")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
.row
|
.row ng-controller="ArchivesController"
|
||||||
.small-12.large-8.columns
|
.small-12.large-8.columns
|
||||||
ul.archives-field
|
ul.archives-field
|
||||||
- 3.times do
|
li ng-repeat=" post in posts "
|
||||||
li
|
a.blog-title ng-click="visit(post.id)"
|
||||||
a.blog-title href="#" 科学是什么
|
|{{ post.title }}
|
||||||
p.tags-field
|
p.tags-field
|
||||||
i.fi-calendar
|
i.fi-calendar
|
||||||
span 2014-2-12
|
span
|
||||||
i.fi-list
|
|{{ post.created_at }}
|
||||||
span 技术
|
i.fi-list
|
||||||
i.fi-pricetag-multiple
|
span
|
||||||
span 生活, 感悟
|
|{{ post.type }}
|
||||||
i.fi-torsos
|
i.fi-pricetag-multiple
|
||||||
span 1010
|
span
|
||||||
i.fi-heart
|
|{{ post.labels }}
|
||||||
span 10
|
i.fi-torsos
|
||||||
|
span
|
||||||
|
|{{ post.visited_count }}
|
||||||
|
i.fi-heart
|
||||||
|
span
|
||||||
|
|{{ post.liked_count }}
|
||||||
|
.no-more-field
|
||||||
|
p ng-show="no_more_flag" 没有更多内容
|
||||||
|
|
||||||
.load-more
|
.load-more
|
||||||
button.small Load More
|
button.small ng-click="load()" ng-show="!loading_flag" Load More
|
||||||
|
button.small ng-show="loading_flag" Loading
|
||||||
|
|
|
@ -2,10 +2,47 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe ArchivesController do
|
describe ArchivesController do
|
||||||
|
|
||||||
|
def posts_data(response)
|
||||||
|
JSON.parse(response.body)["posts"]
|
||||||
|
end
|
||||||
|
|
||||||
describe "GET 'index'" do
|
describe "GET 'index'" do
|
||||||
it "returns http success" do
|
it "json" do
|
||||||
get 'index'
|
get 'index', format: :json
|
||||||
response.should be_success
|
posts_data(response).size.should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "add ten" do
|
||||||
|
posts = create_list(:post_list, 10)
|
||||||
|
get 'index', format: :json
|
||||||
|
posts_data(response).size.should == 10
|
||||||
|
end
|
||||||
|
|
||||||
|
it "add 20" do
|
||||||
|
posts = create_list(:post_list, 20)
|
||||||
|
get 'index', format: :json
|
||||||
|
posts_data(response).size.should == 10
|
||||||
|
end
|
||||||
|
|
||||||
|
it "type filter" do
|
||||||
|
posts = create_list(:post_list, 20)
|
||||||
|
life_posts = create_list(:post_list, 5, type: Post::LIFE)
|
||||||
|
get 'index', type: 'life', format: :json
|
||||||
|
posts_data(response).size.should == 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it "start_with filter" do
|
||||||
|
posts = create_list(:post_list, 10)
|
||||||
|
start_with = posts[4].created_at.to_i.to_s
|
||||||
|
get 'index', start_with: start_with, format: :json
|
||||||
|
posts_data(response).size.should == 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it "load_more" do
|
||||||
|
posts = create_list(:post_list, 20)
|
||||||
|
get 'index', format: :json
|
||||||
|
start_with = JSON.parse(response.body)['start_with']
|
||||||
|
expect(start_with).to eq( posts[9].created_at.to_i.to_s )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -61,4 +61,27 @@ describe BlogsController do
|
||||||
assigns[:comments][1].content.should == 'iloveyou'
|
assigns[:comments][1].content.should == 'iloveyou'
|
||||||
assigns[:comments][1].email.should == 'liuzhen@.com'
|
assigns[:comments][1].email.should == 'liuzhen@.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "get SHOW" do
|
||||||
|
it "#prev, #next" do
|
||||||
|
posts = create_list(:post_list, 3)
|
||||||
|
selected = posts[1]
|
||||||
|
s_prev = posts[0]
|
||||||
|
s_next = posts[2]
|
||||||
|
get :show, id: selected.id
|
||||||
|
expect(assigns(:prev)).to eq(s_prev)
|
||||||
|
expect(assigns(:next)).to eq(s_next)
|
||||||
|
|
||||||
|
selected = posts[0]
|
||||||
|
get :show, id: selected.id
|
||||||
|
expect(assigns(:prev)).to be_nil
|
||||||
|
expect(assigns(:next)).to eq(posts[1])
|
||||||
|
|
||||||
|
selected = posts[2]
|
||||||
|
get :show, id: selected.id
|
||||||
|
expect(assigns(:prev)).to eq(posts[1])
|
||||||
|
expect(assigns(:next)).to be_nil
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :comment do
|
||||||
|
content 'content' * 10
|
||||||
|
type Post::TECH
|
||||||
|
association :post
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :post do
|
||||||
|
title 'this is a post title'
|
||||||
|
content 'content' * 10
|
||||||
|
type Post::TECH
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :post_list, class: Post do
|
||||||
|
sequence(:title) { |n| "#{n}: post title" }
|
||||||
|
content 'content' * 10
|
||||||
|
sequence(:created_at) { |n| n.days.ago }
|
||||||
|
type Post::TECH
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,6 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Post do
|
describe Post do
|
||||||
it "validates should be ok" do
|
it "validates should be ok" do
|
||||||
a = Post.create!(title: 'one', content: '1'*31, type: Post::TECH )
|
expect(create(:post)).to be_true
|
||||||
a.save.should == true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,11 +9,7 @@ require 'rspec/autorun'
|
||||||
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
# ## Mock Framework
|
config.include FactoryGirl::Syntax::Methods
|
||||||
#
|
|
||||||
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
|
||||||
# clear test data
|
|
||||||
|
|
||||||
config.before :each do
|
config.before :each do
|
||||||
DatabaseCleaner.strategy = :truncation
|
DatabaseCleaner.strategy = :truncation
|
||||||
DatabaseCleaner.start
|
DatabaseCleaner.start
|
||||||
|
@ -23,22 +19,6 @@ RSpec.configure do |config|
|
||||||
DatabaseCleaner.clean
|
DatabaseCleaner.clean
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# config.mock_with :mocha
|
|
||||||
# config.mock_with :flexmock
|
|
||||||
# config.mock_with :rr
|
|
||||||
config.mock_with :rspec
|
config.mock_with :rspec
|
||||||
|
|
||||||
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
||||||
#config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
||||||
|
|
||||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
||||||
# examples within a transaction, remove the following line or assign false
|
|
||||||
# instead of true.
|
|
||||||
#config.use_transactional_fixtures = true
|
|
||||||
|
|
||||||
# If true, the base class of anonymous controllers will be inferred
|
|
||||||
# automatically. This will be the default behavior in future versions of
|
|
||||||
# rspec-rails.
|
|
||||||
config.infer_base_class_for_anonymous_controllers = false
|
config.infer_base_class_for_anonymous_controllers = false
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue