【问题标题】:CakePHP JavaScript execution with AJAX使用 AJAX 执行 CakePHP JavaScript
【发布时间】:2012-12-09 07:20:07
【问题描述】:

我在视图中有一个 JavaScript,但在使用 AJAX 加载不同内容后它没有再次执行,所以我想将它放在视图的 <head> 中以与 AJAX 隔离,而不必将它放在文件中,因为它使用来自控制器的 PHP 数组。我该怎么做?有没有办法以 CakePHP 的方式编写 JavaScript 代码,并像 JavaScript 文件一样将其设置为 inline false?

似乎即使是头部的 JavaScript 代码也无法使用 AJAX 执行,所以我应该怎么做呢?我应该将与 JavaScript 相关的 div 放在内容 div 之外还是什么?

这是我的看法:

    <script>
    var geocoder, lat, lng;
    function initialize() {
        var location = <?php echo "\"" . $location . "\""?>;
        location = location.replace(/\+/g, ' ');
        document.getElementById("address").innerHTML = location + " Weather";
        var latlng = new google.maps.LatLng(<?php echo $loc['lat'];?>, <?php echo $loc['lng'];?>);
        var mapOptions = {
            zoom: 12,
            center: latlng,
            navigationControl: false,
            mapTypeControl: false,
            scaleControl: false,
            draggable: false,
            scrollwheel: false,
            disableDoubleClickZoom: true,
            zoomControl: false,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

        <?php $i = 0 ?>
        <?php foreach ($posts as $post): ?>
        var markerLatlng = new google.maps.LatLng(<?php echo h($post['Post']['latitude']); ?>, <?php echo h($post['Post']['longitude']); ?>);
        var marker = new google.maps.Marker({
        position: markerLatlng,
        map: map,
        title: '<?php echo h($post['Post']['temperature']); ?>',
        icon: 'http://chart.apis.google.com/chart?chst=d_map_spin&chld=0.6|0|FF0000|12|_|<?php echo h($post['Post']['temperature']); ?>',
        url: '<?php echo $this->Html->url(array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>'
        });
        google.maps.event.addListener(marker, 'click', function() {
            window.location.href = this.url;
        });
        <?php endforeach; ?>
    }

    function loadScript() {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyBoEBzeiYi-bCaTIlcK7lrNKUyvUfLQqGM&sensor=false&callback=initialize&region=LB";
        document.body.appendChild(script);
    }

    $(document).ready(function(){
        $(".post .toggle").toggle(function(){
            $(".post .toggle").css('background-image','url(../../img/down.png)');
            $(this).css('background-image','url(../../img/up.png)');
            $(".post .description").hide();
            $(this).parent().find(".description").show("slow");
            $(".post").height(100);
            $(this).parent().height(200);},
            function() {$(".post .toggle").css('background-image','url(../../img/down.png)');$(".post").height(100);$(".post .description").hide();$(this).css('background-image','url(../../img/down.png)');
        });
    });

    window.onload = loadScript;
    </script>
    <div id="weather">
    <center><div id="address">&nbsp;</div>
    <p><div id="coords"><?php echo $loc['lat'] . ", " . $loc['lng'];?></div></p></center>
    <div id="weather-menu">
    <?php echo $this->Html->link('Today', 'today/' . $location);?>
    <?php echo $this->Html->link('Yesterday', 'yesterday/' . $location);?>
    <?php echo $this->Html->link('Custom', 'custom/' . $location);?>
    <?php echo $this->Html->link('All', 'all/' . $location);?>
    </div>
    <div id="post-container">
    <?php /*
    if ($posts) {
    echo "<div id=\"post\"><div id=\"temperature\">";
    echo $posts[0]['Post']['temperature'] . "°C</div>";
    if ($posts[0]['Humidity']['humidity'])
        echo "<div id=\"humidity\">" . $posts[0]['Humidity']['humidity'] . "%</div>";
    echo "<div id=\"created\">" . $this->Time->niceShort($posts[0]['Post']['created']) . "              </div>";
        echo "<div id=\"username\">" . $posts[0]['User']['username'] . "</div>";
        echo "<div id=\"condition\">";
        if (strtotime($posts[0]['Post']['created']) > date_sunrise(strtotime($posts[0]         ['Post']['created']), SUNFUNCS_RET_TIMESTAMP, $posts[0]['Post']['latitude'], $posts[0] ['Post']['longitude'],90, 2) && strtotime($posts[0]['Post']['created']) < date_sunset(strtotime($posts[0]['Post']['created']), SUNFUNCS_RET_TIMESTAMP, $posts[0]['Post']['latitude'], $posts[0]['Post']['longitude'],90, 2))      
        echo $this->Html->image('/img/weather-icons/' . $posts[0]['Post']['condition'] . 'A.png');
    else
        echo $this->Html->image('/img/weather-icons/' . $posts[0]['Post']['condition'] . 'B.png');
    echo "</div></div>";
}*/
?>
     <?php


    //$posts = $this->requestAction('/weather/fetch');
        foreach (array_slice($posts, 0) as $post) {
        echo "<div class=\"post\"><div class=\"temperature\">";
        echo $this->Html->link($post['Post']['temperature'] . "°C", array('controller' =>     'posts', 'action' => 'view', $post['Post']['id'])) . "</div>";
    if ($post['Humidity']['humidity'])
        echo "<div class=\"humidity\">" . $post['Humidity']['humidity'] . "%</div>";
    echo "<div class=\"created\">" . $this->Time->niceShort($post['Post']['created']) . "</div>";
    echo "<div class=\"username\">" . $this->Html->link($post['User']['username'], array('controller' => 'users', 'action' => 'view', $post['Post']['user_id'])) . "</div>";
    echo "<div class=\"condition\">";
    if (strtotime($post['Post']['created']) > date_sunrise(strtotime($post['Post']

['created']), SUNFUNCS_RET_TIMESTAMP, $post['Post']['latitude'], $post['Post']['longitude'],90, 2) && strtotime($post['Post']['created']) < date_sunset(strtotime($post['Post']['created']), SUNFUNCS_RET_TIMESTAMP, $post['Post']['latitude'], $post['Post']['longitude'],90, 2))      
        echo $this->Html->image('/img/weather-icons/' . $post['Post']['condition'] . 'A.png');
    else
        echo $this->Html->image('/img/weather-icons/' . $post['Post']['condition'] . 'B.png');
    echo "</div>";
    echo "<div class=\"description\">" . $post['Description']['description'] . "</div>";
    echo "<div class=\"toggle\"></div>";
    echo "</div>";
}
?>
</div>
<div id="side-container">
<div id="map_canvas"></div>
<br/>
<div id ="current"><?php if (isset($w_temp)) echo "Current Temperature: " . $w_temp . "°C" . $this->Html->image('/img/wg.png');?></div>
</div>
<?php
$this->Paginator->options(array(
    'update' => '#content',
    'before' => $this->Js->get('#busy-indicator')->effect('fadeIn', array('buffer' => false)),
    'complete' => $this->Js->get('#busy-indicator')->effect('fadeOut', array('buffer' => false))
));
echo $this->Paginator->prev('« Previous ', null, null, array('class' => 'disabled'));
echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled'));
echo $this->Js->writeBuffer();
?>
<div id="busy-indicator"></div>
</div>

这是我的控制器索引操作:

public function index($date, $location = null) {
    $this->set('location', $location);
    $address = urlencode($location);
    $loc = $this->getLocation($address);
    $this->set('loc', $loc);
    $this->loadModel('Post');
    if ($date == 'all') {
        $this->paginate = array('conditions' => array(
                'latitude BETWEEN ? AND ?' => array(
                    $loc['lat'] - 0.05, $loc['lat'] + 0.05), 
                'longitude BETWEEN ? AND ?' => array(
                        $loc['lng'] - 0.05, $loc['lng'] + 0.05)
                ),
            'order' => array('Post.created' => 'desc'),
            'limit' => '5');
        $this->set('posts', $this->paginate('Post'));
    }
    else if ($date == 'today') {
        $this->set('posts', $this->Post->find('all', array(
            'conditions' => array(
                'latitude BETWEEN ? AND ?' => array(
                    $loc['lat'] - 0.05, $loc['lat'] + 0.05), 
                'longitude BETWEEN ? AND ?' => array(
                        $loc['lng'] - 0.05, $loc['lng'] + 0.05),
                'Post.created >' => date('Y-m-d H:i:s', strtotime("-1 day"))
                ),
            'order' => array('Post.created' => 'desc'))));
    }
    else if ($date == 'yesterday') {
        $this->set('posts', $this->Post->find('all', array(
            'conditions' => array(
                'latitude BETWEEN ? AND ?' => array(
                    $loc['lat'] - 0.05, $loc['lat'] + 0.05), 
                'longitude BETWEEN ? AND ?' => array(
                        $loc['lng'] - 0.05, $loc['lng'] + 0.05),
                'Post.created >' => date('Y-m-d H:i:s', strtotime("-2 day")),
                'Post.created <' => date('Y-m-d H:i:s', strtotime("-1 day"))
                ),
            'order' => array('Post.created' => 'desc'))));
    }
    $this->wunder($location);
}

【问题讨论】:

  • 如果您包含您的代码和标记,它有助于找出您的问题。我怀疑当它正在访问或引用的元素可用时,即在元素准备好 DOM 之后,您没有运行您所引用的任何脚本。此外,如果您在脚本运行时在浏览器中监控 Javascript 控制台,您可能会遗漏正在发生的错误。我建议使用 Chrome 控制台或 Firefox 的 Firebug 控制台。
  • 你能否详细说明你的第一句话“我在视图中有一个 JavaScript,但它没有用 AJAX 执行”你是说它没有用 AJAX 执行是因为有问题还是因为你不需要它到?当您说“与 AJAX 隔离”时,您是指美学上的吗?你只想要单独的代码块?

标签: javascript ajax cakephp


【解决方案1】:

谢谢你们。我只需要将它添加到我的 javascript 代码中:

var pathname = window.location.pathname;
window.onload = loadScript;
$(document).ready(function() {
    $.ajax({
        url: pathname,
        success: function(){
          loadScript();
        }
    })
});

【讨论】:

    【解决方案2】:

    你写道:

    我在视图中有一个 JavaScript,但之后它不再执行 使用 AJAX 加载不同的内容

    我只是简要地查看了您在做什么,但我没有立即看到您在哪里发出 AJAX 请求。正如其他人所指出的那样,澄清这一点会有所帮助。但是,请注意,在使用 AJAX 加载新内容后,如果您的脚本对任何替换的内容都有事件处理程序,那么您将需要在 Javascript 中销毁并重新创建事件处理程序(即使您将其替换为相同的 DOM 元素)。

    至此:

    有没有办法以 CakePHP 的方式编写 JavaScript 代码并将其设置为 inline false 和 JavaScript 文件一样吗?

    因此,您执行此操作的方式与在 cakePHP 中引用外部源文件的方式基本相同,您可以替换:

    <script>
    ...
    </script>
    

    以下内容:

    $this->Html->ScriptBlock('your javascript here', array('inline'=>false));
    

    然后在该部分确保您拥有(对于 cakePHP 2.1 或更高版本):

    echo $this->fetch('script');
    

    或(对于 cakePHP 2.0x 或更早版本)

    $scripts_for_layout();
    

    【讨论】:

      【解决方案3】:

      由于您使用“AJAX”将脚本注入到页面中,我想,您这样做的方式可能是使用 jQuery 或任何通过 element.innerHTML = content 将您的内容拉入 DOM,我错了吗?

      但是在 element.innerHTML 中传递的脚本不会执行,这就是 jQuery 用来分割 HTML 响应的内容!

      恕我直言,最好的方法是仅使用“AJAX”将数据从您的 CakePHP 应用程序获取到 javascript 前端(带有 JSON 响应),然后您将在您的 javascript 代码中使用这些数据来显示您的图表。它会更有效率,而且你不会遇到鞋底所说的丢失 DOM 元素引用的问题。

      或者你可以用这个 hack 偷懒的做:

      <img style="display:none" src="data:image/png,script" onerror="
       console.log('Hey I am javascript code running as long as javascript isnt disabled!');
      "/>
      

      【讨论】:

        【解决方案4】:
        <script>
        
        // this is new invention like JSON  it seem cute function but it is not
        
        
        function connect_php() {
        jQuery(document).ready(function($){
        
        
            setTimeout(function() {
               $("#final_result").css('display', 'block');
            }, 4000); //here 1000 means 1 second
        
        });
        
        }
        
        jQuery(document).ready(function($){
        
            (function a(x) {
                // The following condition
                // is the base case.
                if ( ! x) {
                    return;
                }
                a(--x);
                event.preventDefault();
                $( "#aform" ).submit();
                connect_php();
            })(10);
            
        });
        
        
        
        </script>
        

        如果你有 php for 循环做某事必须等待,这将在 php 完成或你的循环完成后从 php 发送消息到 JS 中定义的 JavaScript 从开始发送消息

        【讨论】:

          猜你喜欢
          • 2013-10-27
          • 1970-01-01
          • 2018-05-20
          • 2017-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-05
          • 1970-01-01
          相关资源
          最近更新 更多