我的模块的 View 页面中有一个 foreach 循环,它从 Controller 检索图像网格(数字由“items_top”确定)。问题是所有项目都同时加载,因为此时没有设置分页。
这是我的 View 的代码:
<div class="row row-sm padder-lg ">
<?php
foreach ($top->tracks->track as $key => $value)
{
if($key >= $this->config->item("items_top"))
return false;
$image = $value->image[3]->text;
if($image == '')
$image = $value->image[2]->text;
if($image == '')
$image = base_url()."assets/images/no-cover.png";
?>
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
<div class="item">
<div class="pos-rlt">
<a href="#">
<div class="item-overlay opacity r r-2x bg-black">
<div class="center text-center m-t-n">
<i class="icon-control-play i-2x"></i>
</div>
</div>
<a href="#">
<div class="r r-2x img-full" style="background:url('<?php echo $image; ?>') no-repeat top center; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover;">
<div style="height:180px;overflow:hidden;"></div>
</div>
</a>
</div>
<div class="padder-v">
<a href="#" class="text-ellipsis"><?php echo $value->name; ?></a>
<a href="#" class="text-ellipsis text-xs text-muted"><?php echo $value->artist->name; ?></a>
</div>
</div>
</div>
<?php
}
?>
<script>
$(".nav-sidebar li").removeClass("active");
$("#topTrack").addClass('active');
</script>
</div>
这是我的函数助手:
function _curl($url) {
$CI =& get_instance();
$ch = curl_init();
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,15);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);
if(strtolower(parse_url($url, PHP_URL_SCHEME)) == 'https')
{
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,1);
}
if($CI->config->item("proxy") != '')
{
curl_setopt($ch, CURLOPT_PROXY, $CI->config->item("proxy"));
}
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function getTopTracks($artist = false)
{
$CI =& get_instance();
$artist = econde($artist);
$url = "http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks&api_key=".$CI->config->item("lastfm")."&format=json&limit=60&page=3";
$file_cache = 'cache/tracks_'.sha1("toptracks").".cache";
if($cache)
{
$json = $cache;
if (time()-filemtime($file_cache) > 24 * 3600) {
// file older than 24 hours
@unlink($file_cache);
}
}
else
{
$json = _curl($url);
if($CI->config->item("use_cache") == "1")
write_file($file_cache, $json);
}
if(!$artist)
$json = str_ireplace("toptracks","tracks",$json);
else
$json = remove_banned($json,true) ;
$json = str_ireplace("#text","text",$json);
$json = str_ireplace(":totalResults","",$json);
return remove_banned($json) ;
}
这是我的 Controller :
public function getTopTracks($return = false,$page = false)
{
$data['page'] = $page;
$data['top'] = json_decode(getTopTracks());
if(count($data['top']->tracks->track) <=1)
{
$this->config->set_item("auto_country", '0');
$data['top'] = json_decode(getTopTracks());
}
return $this->load->view(getTemplate('topTracks'),$data,$return);
}
我需要对循环进行切片以对这些项目进行分页,我希望能够在底部添加一个“加载更多”按钮,但问题是 Ajax,我不能使用 $page = (int )getFromExternalInput(); 因为循环调用的是公共(public)函数而不是 url。
分割这个循环的正确方法是什么?
最佳答案
I edited the function helper in my question with the code asked for...hope this could be helpful for an answer. Thanks
好的,根据您的附加信息更新我的答案,我根据新信息创建了一个工作示例。但是我确实必须为自己创建一个沙箱,这不会 100% 反射(reflect)您的代码。不过,我觉得您应该能够从这个答案中得到一些东西,并且您应该能够在您自己的代码中实现它。
代码确实需要一些优化
我将缓存文件保存在/application/cache/lastfm
缓存对于这里的分页来说可能有点问题,但我尽我所能想出了一个可行的例子
application/config/lastfm.php
$config['url'] = 'http://ws.audioscrobbler.com/2.0/';
/**
*
*/
$config['API_KEY'] = '';
/**
*
*/
$config['limit'] = 12;
/**
*
*/
$config['cache_time'] = 24 * 3600;
/**
*
*/
$config['proxy'] = "";
application/libraries/curl.php
class Curl
{
protected $handle;
public function __construct()
{
$this->_init();
}
/**
*
* @return type
*/
protected function _init()
{
if(!in_array('curl', get_loaded_extensions()))
return log_message('error', 'curl extension is not loaded!');
$this->handle = curl_init();
if(!$this->handle) {
return log_message('error', 'could not create curl handle!');
}
}
/**
*
* @param type $url
* @return type
*/
public function fetch($url)
{
$this->setOptions($url);
$response = curl_exec($this->handle);
if($errno = curl_errno($this->handle)){
log_message('error', 'Curl Response Error: ' . curl_strerror($errno));
}
curl_close($this->handle);
return ($errno === 0) ? $response : false;
}
/**
*
* @param type $url
* @return type
*/
protected function setOptions($url)
{
if(strtolower(parse_url($url, PHP_URL_SCHEME)) == "https"){
curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 1);
}
$proxy = $this->config->item('proxy', 'lastfm');
if(!empty($proxy)){
curl_setopt($this->handle, CURLOPT_PROXY, $proxy);
}
curl_setopt($this->handle,CURLOPT_FAILONERROR,true);
curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->handle, CURLOPT_URL, $url);
return;
}
/**
*
* @param type $name
* @return type
*/
public function __get($name)
{
$instance =&get_instance();
return $instance->$name;
}
}
application/controllers/tracks.php
class Tracks extends App_Controller
{
public function __construct()
{
parent::__construct();
$this->load->config('lastfm', true);
$this->load->model('lastfm_model');
}
public function index()
{
$tracks = $this->lastfm_model->getTracks(1);
$this->load->view($this->template, array(
'content' => 'lastfm/tracks',
'tracks_view' => $this->load->view('lastfm/partials/tracks', array(
'tracks' => $tracks,
'statistics' => $tracks['data']->tracks->attr
), true)
));
}
public function get($pageId=0)
{
$tracks = $this->lastfm_model->getTracks($pageId, true);
if($pageId > $tracks['data']->tracks->attr->totalPages){
return;
}
$this->load->view('lastfm/partials/tracks', array(
'tracks' => $tracks,
'statistics' => $tracks['data']->tracks->attr
));
}
}
application/models/lastfm_model.php
class LastFM_Model extends CI_Model
{
/**
*
* @var type
*/
protected $options;
/**
*
* @var type
*/
protected $cache;
/**
*
* @var type
*/
protected $method;
/**
*
* @var type
*/
protected $byPassCache = false;
public function __construct()
{
parent::__construct();
$this->options = $this->config->config['lastfm'];
}
/**
*
* @param type $page
*/
public function getTracks($page=0, $bypass_cache=false, $method='chart.gettoptracks')
{
$this->method = $method;
$this->cache = $this->_getCachePath();
$this->byPassCache = $bypass_cache;
$url= $this->_buildUrl($page);
if($bypass_cache){
return array(
'src' => 'curl',
'data' => $this->_parseContent($this->_fetch($url), false)
);
}
if($cache = $this->_getCache()){
return array(
'src' => 'cache',
'data' => $this->_parseContent($cache)
);
}
return array(
'src' => 'curl',
'data' => $this->_parseContent($this->_fetch($url), false)
);
}
/**
*
* @param type $page
* @return type
*/
protected function _buildUrl($page=0)
{
$query_data = array(
'method' => $this->method,
'format' => 'json',
'page' => $page,
'limit' => $this->options['limit'],
'api_key' => $this->options['API_KEY']
);
$query = http_build_query($query_data);
return $this->options['url'] . '?' . $query;
}
/**
*
* @param type $url
* @return type
*/
protected function _fetch($url)
{
$this->load->library('curl');
$data = $this->curl->fetch($url);
$data = str_ireplace(array('#text', '@attr'), array('text', 'attr'), $data);
if(!$this->byPassCache){
$this->_setCache($data);
}
return ($data) ? $data : false;
}
/**
*
* @return type
*/
protected function _getCachePath()
{
return APPPATH . "cache/lastfm/{$this->method}.cache";
}
/**
*
* @param type $data
* @return type
*/
protected function _setCache($data)
{
if(file_exists($this->cache)){
unlink($this->cache);
}
if(!empty($data)){
return file_put_contents($this->cache, $data);
}
}
/**
*
* @return type
*/
protected function _getCache()
{
return ( file_exists($this->cache) && ( time() - filemtime($this->cache) ) < $this->options['cache_time'] )
? $this->cache
: false;
}
/**
*
* @param type $content
* @param type $cache
* @return type
*/
protected function _parseContent($content, $cache=true)
{
if($cache)
$content = file_get_contents($content);
return json_decode($content);
}
}
application/views/lastfm/tracks.php
<div id="track_list">
<?php echo $tracks_view; ?>
</div>
<script>
var SITE_URL = "<?php echo site_url();?>";
</script>
<script>
/** LastFm **/
(function($){
var lastFm = {
/**
*
* @type type
*/
options : {
cache : false,
url : undefined,
type : "GET",
dataType : "html",
data : {}
},
/**
*
* @returns {undefined}
*/
init : function(){
this.More = $("a#more");
this.trackList = $("#track_list");
this.trackList.on('click', this.More, $.proxy(this.handleEventClick, this));
},
/**
*
* @param {type} event
* @returns {undefined}
*/
handleEventClick : function(event){
event.preventDefault();
var target, pageId;
target = event.target;
pageId = parseInt($(target).attr('data-pageId'));
$(target).remove();
this.pageID = pageId+1;
this.fetch(this.pageID);
},
/**
*
* @returns {undefined}
*/
fetch : function(pageId){
this.options.url = SITE_URL + "/tracks/get/"+pageId;
this.dojax().then(
$.proxy(this.handleResponse, this),
$.proxy(this.handleErrors, this)
);
},
/**
*
* @returns {unresolved}
*/
dojax : function(){
return $.ajax(this.options).promise();
},
/**
*
* @param {type} response
* @returns {undefined}
*/
handleResponse : function(response){
this.More.remove();
this.trackList.append(response);
$("html, body").animate({
scrollTop : $("[data-pageSlideId="+this.pageID+"]").filter(':last').offset().top
});
},
/**
*
* @param {type} error
* @returns {undefined}
*/
handleErrors : function(error){
}
};
lastFm.init();
}(jQuery));
</script>
application/views/lastfm/partials/tracks.php
<div id="page_<?php echo $statistics->page;?>">
<?php
$columnsPerRow = 4;
foreach(array_chunk($tracks['data']->tracks->track, $columnsPerRow) as $track): ?>
<div class="row" data-pageSlideId="<?php echo $statistics->page;?>">
<?php foreach($track as $trac):?>
<?php $image = (!empty($trac->image[2]->text)) ? $trac->image[2]->text : false;?>
<div class="large-3 medium-6 columns text-center" >
<div class="panel" style="background: url('<?php echo $image;?>') no-repeat;background-size: cover;">
<h6><?php echo $trac->name;?></h6>
<h5><?php echo $trac->artist->name;?></h5>
</div>
</div>
<?php endforeach;?>
</div>
<?php endforeach; ?>
</div>
<div class="row">
<div class="large-12 columns text-center">
<a href="" class="button" id="more" data-pageId="<?php echo $statistics->page;?>">Load More...</a>
</div>
</div>
关于javascript - 我如何使用 CodeIgniter 在 Ajax 中切片数组以进行分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28381066/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev