【问题标题】:Filter data in ng-repeat to display only the clicked item with Angularjs过滤 ng-repeat 中的数据以仅使用 Angularjs 显示单击的项目
【发布时间】:2020-06-26 22:19:18
【问题描述】:

请帮忙。 我已经使用 Angularjs 显示了 7 个事件的列表。我想当我点击某个事件的<h2>(事件名称)时,打开一个显示来自数据库的相同数据但仅针对被点击的事件的覆盖。 我确信“过滤器”会起作用,但似乎我做错了什么。 这是我的代码。 ng-app 和 ng-controller 在<main> 标签中。 Angularjs 版本:1.7.9

我的 HTML:

<main ng-app="eventsApp" ng-controller="eventsCtrl">

    <!-- Overlay that holds and displays a single event -->
    <div>
        <div ng-repeat="x in singlePageEvent | filter:hasName(x.eventName)">
            <div>
                <img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
                <h2 class="event-name">{{x.eventName}}</h2>
                <p>{{x.eventTime}}</p>
                <p>{{x.eventPlace}}</p>
            </div>
        </div>
    </div>

    <!-- A list with all the events -->
    <div ng-repeat="x in events">
        <div>
            <img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
            <h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
            <p>{{x.eventTime}}</p>
            <p>{{x.eventPlace}}</p>
        </div>
    </div>

</main>

我的脚本:

let eventsApp = angular.module('eventsApp', []);

下面的这个过滤器根本不起作用。它继续显示所有事件。

eventsApp.filter('hasName', function() {
    return function(events, evName) {
        var filtered = [];
        angular.forEach(events, function(ev) {
            if (ev.eventName && ev.eventName.indexOf(evName) >-1) {
                filtered.push(ev);
            }
        });
        return filtered;
    }
});

eventsApp.controller('eventsCtrl', function($scope, $http) {
    let x = window.matchMedia("(max-width: 450px)");
    let singleEventOverlay = angular.element(document.querySelector('div.single-event.overlay'));
    let singleEvent = singleEventOverlay;

    function responsiveEventImages(x) { //this displays the list with events
        if (x.matches) {
            $http.get('./includes/events_res.inc.php').then(function(response) {
                $scope.events = response.data.events_data;
            });
        } else {
            $http.get('./includes/events.inc.php').then(function(response) {
                $scope.events = response.data.events_data;
            });
        }
    }

...然后通过调用singleEventOpen() 会出现叠加层,但它会显示所有数据,而不仅仅是点击事件

    $scope.singleEventOpen = function(singleEvent) {
        let clickedEvent = singleEvent.eventName; //I got the value of each h2 click thanx to @georgeawg but now what?
        console.log("Fetching info for ", singleEvent.eventName);

        $http.get('./includes/single_event.inc.php').then(function(response) {
            $scope.singlePageEvent = response.data.events_data;
        });

        singleEventOverlay.removeClass('single-event-close').addClass('single-event-open');
    }
});

带有数据库提取的 php 文件工作正常,所以我不会在这里显示它。 我应该怎么做才能使覆盖仅显示&lt;h2&gt;被点击的事件?

Here is a pic of the list with events

Here is a pic of the overlay

提前感谢。

已编辑 我得到了每个h2 的价值点击thanx 到@georgeawg 但现在呢?

更新 嘿,非常感谢@georgeawg。经过多次尝试,我终于做到了:

$scope.singleEventOpen = function(singleEvent) {
    $http.get('./includes/single_event.inc.php').then(function(response) {
        let allEvents = response.data.events_data;
        for (var i = 0; i < allEvents.length; i++) {
            singleEvent = allEvents[i];
        }
    });
    console.log('Fetching data for', singleEvent);
    $scope.ex = singleEvent;
});

而且效果很好。

【问题讨论】:

    标签: javascript angularjs filter angularjs-ng-repeat


    【解决方案1】:

    更改ng-click 以将参数传递给singleEventOpen 函数:

    <div ng-repeat="x in events">
        <div>
            <img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
            <h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
            <p>{{x.eventTime}}</p>
            <p>{{x.eventPlace}}</p>
        </div>
    </div>
    

    然后使用该参数:

    $scope.singleEventOpen = function(singleEvent) {
        console.log("Fetching info for ", singleEvent.eventName);
        //...
        //Fetch and filter the data
    
        $scope.ex = "single item data";
    }
    

    添加参数是了解点击了哪个&lt;h2&gt; 元素的关键。


    更新

    不要在叠加层中使用ng-repeat,只显示单个项目:

    <!-- Overlay that holds and displays a single event -->
    ̶<̶d̶i̶v̶ ̶n̶g̶-̶r̶e̶p̶e̶a̶t̶=̶"̶x̶ ̶i̶n̶ ̶s̶i̶n̶g̶l̶e̶P̶a̶g̶e̶E̶v̶e̶n̶t̶ ̶|̶ ̶f̶i̶l̶t̶e̶r̶:̶h̶a̶s̶N̶a̶m̶e̶(̶x̶.̶e̶v̶e̶n̶t̶N̶a̶m̶e̶)̶"̶>̶
    <div ng-if="ex"">
        <div>
            <img ng-src="{{ex.eventImgSrc}}" alt="{{ex.eventImgName}}"/>
            <h2 class="event-name">{{ex.eventName}}</h2>
            <p>{{ex.eventTime}}</p>
            <p>{{ex.eventPlace}}</p>
        </div>
    </div>
    

    【讨论】:

    • 我刚试过这个。不幸的是,它不起作用。控制台中的日志显示Fetching info for undefined,它有点弄乱了singleEvent.removeClass() 代码,因此覆盖层根本不会出现。我应该用过滤器做点什么吗?
    • 您确定在ng-click 中添加了参数吗?即ng-clicked="singleEventOpen(x)". 添加参数是了解点击了哪个&lt;h2&gt; 元素的关键。
    • 对不起...ng-click 的参数没问题,但我犯了另一个错误——我无意中将代码放到了函数外部的错误位置。现在Fetching info for 显示我单击的正确事件名称,但removeClass() 函数停止工作。它说:singleEvent.removeClass 不是一个函数,因此覆盖层保持关闭,因为它需要删除和添加它的类。
    猜你喜欢
    • 1970-01-01
    • 2014-10-15
    • 1970-01-01
    • 2018-06-28
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多